Published on

Swiftda Generics

Authors

Swift Generics turli ma'lumot turlari bilan ishlatilishi mumkin bo'lgan yagona funksiya va class (yoki boshqa turlar) yaratish imkonini beradi.

Bu kodimizni qayta ishlatishga yordam beradi.

Swiftda Generic funksiya

Swiftda har qanday turdagi ma'lumotlar bilan ishlatilishi mumkin bo'lgan funksiya yaratishimiz mumkin. Bunday funksiya Generic Funksiya deb ataladi.

Swiftda generic funksiya yaratish usuli:

// generic funksiya yaratish
func displayData<T>(data: T){
  ...
}

Bu yerda:

  • displayData() nomli generic funksiya yaratdik
  • Burchakli qavslar <> ichida ishlatiladigan T tur parametri deyiladi
  • Va funksiyaga uzatilgan qiymat turiga asoslanib, T o'sha ma'lumot turi (Int, String va hokazo) bilan almashtiriladi

Tur parametriga istalgan nom berishimiz mumkin: <S>, <Element> va hokazo. Ammo odatda biz T dan foydalanamiz.

Misol:

  // generic funksiya yaratish
func displayData<T>(data: T) {
  print("Generic Funksiya:")
  print("Uzatilgan ma'lumot:", data)
}

// String bilan ishlaydigan generic funksiya
displayData(data: "Swift")

// Int bilan ishlaydigan generic funksiya
displayData(data: 5)

Natija:

Generic Funksiya:
Uzatilgan ma'lumot: Swift
Generic Funksiya:
Uzatilgan ma'lumot: 5

Yuqoridagi misolda <T> tur parametrli displayData() nomli generic funksiya yaratdik.

Endi generic funksiyani chaqirganimizda:

displayData(data: "Swift")

string qiymatni uzatdik, shuning uchun T o'rin egasi parametri avtomatik ravishda String bilan almashtiriladi.

Xuddi shunday, generic funksiyaga Int uzatganimizda:

displayData(data: 5)

o'rin egasi Int bilan almashtiriladi.

Generic Class

Generic funksiyaga o'xshab, har qanday turdagi ma'lumotlar bilan ishlatilishi mumkin bo'lgan class ham yaratishimiz mumkin. Bunday class Generic Class deb ataladi.

Keling, misolni ko'raylik:

// generic class yaratish
class Information<T> {

  // T turli property
  var data: T

  init (data: T) {
    self.data = data
  }

  // T turli o'zgaruvchini qaytaruvchi metod
  func getData() -> T {
    return self.data
  }
}

// Int ma'lumoti bilan generic classni initsializatsiya qilish
var intObj = Information<Int>(data: 6)
print("Generic Class qaytaradi:", intObj.getData())

// String ma'lumoti bilan generic classni initsializatsiya qilish
var strObj = Information<String>(data: "Swift")
print("Generic Class qaytaradi:", strObj.getData())

Natija:

Generic Class qaytaradi: 6
Generic Class qaytaradi: Swift

Yuqoridagi misolda Information nomli generic class yaratdik. Bu class har qanday turdagi ma'lumotlar bilan ishlash uchun ishlatilishi mumkin.

class Information<T> {...}

Information ning ikkita obyektini yaratdik:

var intObj = Information<Int>(data: 6)

var strObj = Information<String>(data: "Swift")

Bu yerda:

  • intObj β€” tur parametri T Int bilan almashtirildi. Endi Information butun son ma'lumotlari bilan ishlaydi
  • strObj β€” tur parametri T String bilan almashtirildi. Endi Information string ma'lumotlari bilan ishlaydi

Genericsda tur cheklovlari

Umuman olganda, tur parametri har qanday ma'lumot turini qabul qilishi mumkin (Int, String, Double, ...).

Ammo agar genericsni faqat ma'lum turlar uchun (masalan, faqat raqamli turlar) ishlatmoqchi bo'lsak, tur cheklovlaridan foydalanishimiz mumkin.

Tur cheklovi yaratish usuli:

func addition<T: Numeric>(num1: T, num2: T) {
  ...
}

Bu yerda <T: Numeric> tur parametriga cheklov qo'shadi. Bu T Numeric protocoliga mos kelishi kerakligini belgilaydi.

Numeric β€” Int va Double kabi raqamli qiymatlar uchun o'rnatilgan protocol.

Misol:

// tur cheklovi bilan generic funksiya yaratish
func addition<T: Numeric>(num1: T, num2: T) {

  print("Yig'indi:", num1 + num2)
}

// Int qiymatni uzatish
addition(num1: 5, num2: 10)

// Double qiymatni uzatish
addition(num1: 5.5, num2: 10.8)

Natija:

Yig'indi: 15
Yig'indi: 16.3

Yuqoridagi misolda addition() nomli generic funksiya yaratdik. Quyidagi ifodaga e'tibor bering:

<T: Numeric>

Bu yerda generic funksiya tur cheklovi bilan yaratilgan. Bu addition() faqat Numeric protocoliga mos keladigan ma'lumot turlari (Int, Double va hokazo) bilan ishlashi mumkinligini bildiradi.

Agar boshqa turlarni, masalan String ni uzatishga harakat qilsak, xato olamiz: argument type 'String' does not conform to the expected type 'Numeric'.

Genericsning afzalliklari

1. Kodni qayta ishlatish

Swiftda generics yordamida turli ma'lumot turlari bilan ishlaydigan kod yozishimiz mumkin. Masalan,

func genericFunction<T>(data: T) {...}

Bu yerda generics funksiya yaratdik. Xuddi shu funksiyani butun son ma'lumotlari, string ma'lumotlari va hokazolarda amallarni bajarish uchun ishlatish mumkin.

2. Kolleksiyalar bilan ishlatish

Swiftda array generics kontseptsiyasidan foydalanadi. Masalan,

// butun son turli array yaratish
var list1: Array<Int> = []

// string turli array yaratish
var list2: Array<String> = []

Bu yerda Int qiymatlarni saqlaydigan list1 array va String qiymatlarni saqlaydigan list2 array.

Arraylarga o'xshab, dictionarylar ham Swiftda generic hisoblanadi.