Published on

Swiftda Initializer

Authors

Initializer — bu class yoki struct obyektini yaratish uchun ishlatiladigan maxsus funksiya turi.

Swiftda initializer yaratish uchun init() metodidan foydalanamiz. Masalan,

class Wall {
  ...

  // initializer yaratish 
  init() {
    // boshlang'ich qiymatlarni berish
    ... 
  }
} 

Bu yerda init() metodi — Wall classining initializeri.

Misol:

// class e'lon qilish
class Wall {
  var length: Double     // uzunlik

  // propertyni boshlang'ich qiymat bilan to'ldirish uchun initializer
  init() {
    length = 5.5
    print("Devor yaratilmoqda.")
    print("Uzunlik = ", length)
  }
}

// obyekt yaratish
var wall1 = Wall()

Natija:

Devor yaratilmoqda.
Uzunlik = 5.5

Yuqoridagi misolda init() nomli initializer yaratdik. Initializer ichida length propertyga qiymat berdik.

Quyidagi qatorga e'tibor bering:

// obyekt yaratish
var wall1 = Wall()

Bu yerda wall1 obyekti yaratilganda init() initializer chaqiriladi. Va length propertyga 5.5 qiymati beriladi.

Parametrli Initializer

Swift initializeri bir yoki bir nechta parametrlarni qabul qilishi mumkin. Bunday initializerlar parametrli initializer deyiladi.

Keling, misolni ko'raylik:

class Wall {
  
  var length: Double     // uzunlik
  ...
  
  // parametrli initializer
  init(length: Double) {

    self.length = length
  } 
}

// obyekt yaratish
var wall1 = Wall(length: 10.5)

Bu yerda:

  • init(length: Double)length parametrli initializer
  • var wall1 = Wall(length: 10.5)length parametriga 10.5 qiymatini uzatish
  • self.length = lengthlength parametridagi qiymatni (10.5) length propertyga berish
  • self.lengthlength propertysi joriy obyektga (wall1) tegishli ekanligini bildiradi

Misol:

// class e'lon qilish
class Wall {
  var length: Double     // uzunlik
  var height: Double     // balandlik

  // propertylarni boshlang'ich qiymat bilan to'ldirish uchun parametrli initializer
  init(length: Double, height: Double) {
    self.length = length
    self.height = height
  }

  func calculateArea() -> Double {
    return length * height
  }
}

// obyekt yaratish va propertylarni to'ldirish
var wall1 = Wall(length: 10.5, height: 8.6)
var wall2 = Wall(length: 8.5, height: 6.3)

print("Devor 1 yuzasi: ", wall1.calculateArea())
print("Devor 2 yuzasi: ", wall2.calculateArea())

Natija:

Devor 1 yuzasi: 90.3
Devor 2 yuzasi: 53.55

Yuqoridagi misolda ikki parametrli init() initializer yaratdik: length va height. Quyidagi ifodalarni ko'rib chiqing:

var wall1 = Wall(length: 10.5, height: 8.6)
var wall2 = Wall(length: 8.5, height: 6.3)

Bu yerda Wall classidan obyekt yaratishda propertylar uchun qiymatlarni argument sifatida uzatamiz.

Propertylar shunday boshlang'ich qiymatlarga ega bo'lgandan so'ng, calculateArea() metodi bilan devor yuzasini hisoblaymiz.

Initializer Overloading

Swift Initializerlarini funksiya overloading singari overload qilish mumkin.

Initializer overloadingda ikki yoki undan ortiq initializerlar bir xil nomga ega bo'lishi mumkin, agar ularning parametrlari turi yoki soni boshqa-boshqa bo'lsa.

Va obyekt yaratilayotganda uzatilgan argumentlarga qarab, mos initializer chaqiriladi.

Keling, misolni ko'raylik:

class Person {
  var age: Int     // yosh

  // 1. argumentsiz initializer
  init() {
    age = 20
  }

  // 2. argumentli initializer
  init(age: Int) {
    self.age = age
  }

  // yoshni qaytaruvchi metod
  func getAge() -> Int {
    return age
  }
}

var person1 = Person()
var person2 = Person(age: 23)

print("Person1 yoshi:", person1.getAge())
print("Person2 yoshi:", person2.getAge())

Natija:

Person1 yoshi: 20
Person2 yoshi: 23

Yuqoridagi misolda bitta age propertyga ega Person classi yaratdik.

Shuningdek, ikki xil initializer e'lon qildik: init() va init(age: Int).

  • person1 obyektiga hech qanday argument uzatilmadi, shuning uchun birinchi initializer chaqirildi. Demak, age ga 20 qiymati berildi.
  • person2 ga argument sifatida 23 uzatildi. Shuning uchun ikkinchi initializer chaqirildi va age ga 23 qiymati berildi.

getAge() metodi age qiymatini qaytaradi va biz uni person1 va person2 yoshini chop etish uchun ishlatamiz.

Convenience Initializer

Oldingi misollarda biz e'lon qilgan initializerlar classning asosiy initializerlari edi. Bu asosiy initializerlar designated initializer ham deyiladi.

Ammo class uchun ikkilamchi/yordamchi initializer ham yaratish mumkin — bu convenience initializer deyiladi.

Convenience initializer yaratish uchun initializer oldidan convenience kalit so'zini ishlatamiz. Masalan,

class University {
  
  var name: String     // nomi
  var rank: String     // reytingi
  
  init(name: String, rank: String) {
    self.name = name
    self.rank = rank
  }

  // convenience init e'lon qilish  
  convenience init() {
    self.init(name: "Kathmandu University", rank: "1st")
  }
  
}

var university1 = University()
print(university1.name)
print("Reyting:", university1.rank)

Natija:

Kathmandu University
Reyting: 1st

Yuqoridagi misolda designated initializer: init() va convenience initializer: convenience init() yaratdik.

Convenience initializer ichida designated initializerni chaqirdik va propertyga qiymatlar berdik.

convenience init() {
  self.init(name: "Kathmandu University", rank: "1st")
}

university1 obyekti yaratilganda convenience initializer chaqiriladi.

// convenience initializer ishlatish
var university1 = University() 

Bu kodimizni designated initializerni chaqirishga qaraganda ancha toza qiladi:

// designated initializerni chaqirish
var university1 = University(name: "Kathmandu University", rank: "1st") 

Convenience Initializerlar stored propertylarga standart qiymatlar berish kerak bo'lganda juda foydali.

Failable Initializer

Ba'zi hollarda initializerlar ishga tushishi yoki tushmasligi mumkin, bu failable initializer deyiladi.

Failable initializer yaratish uchun init kalit so'zidan keyin savol belgisi (?) qo'yamiz va agar nimadir noto'g'ri bo'lsa, nil qaytaramiz. Masalan,

class File {

  var folder: String     // papka

  // failable initializer
  init?(folder: String) {

    // bo'sh yoki yo'qligini tekshirish
    if folder.isEmpty {
      print("Papka topilmadi") // 1-natija
      return nil
    }
    self.folder = folder
  }
}

// file obyekti yaratish
var file = File(folder: "")
if (file != nil) {
  print("Fayl muvaffaqiyatli topildi")
}
else {
  print("Faylni topishda xato") // 2-natija
}

Natija:

Papka topilmadi
Faylni topishda xato

Yuqoridagi misolda folder parametrli failable initializer init?() yaratdik.

Va if operatori va isEmpty propertysi yordamida

if (folder.isEmpty) { return nil }

papka bo'sh yoki yo'qligini tekshirdik va agar bo'sh bo'lsa nil qaytardik.

file obyekti uchun bo'sh satr "" uzatdik, bu initialization xatosini keltirib chiqardi, shuning uchun avval ichidagi operator bajarildi, keyin nil qaytardi.

Va nihoyat, else bloki ichidagi operator bajarildi.

Struct uchun Memberwise Initializer

Swiftda struct bilan ishlashda initializer yaratish shart emas. Swift avtomatik ravishda memberwise initializer yaratadi. Masalan,

struct Person {
  
  var name: String     // ism
  var age: Int         // yosh
}

Bu yerda Person structi ichida hech qanday initializer yaratmadik. Ammo Swift avtomatik ravishda memberwise initializer yaratadi:

var person1 = Person(name: "Dwight", age: 43)

Bu yerda qavslar () ichidagi qiymatlar avtomatik ravishda structning mos propertylariga beriladi. Bu memberwise initializer deyiladi.

Misol:

struct Person {

  // ikki ta property e'lon qilish  
  var name: String     // ism
  var age: Int         // yosh
}

// memberwise initializer bilan Person obyekti  
var person1 = Person(name: "Dwight", age: 43)

print("Ism:", person1.name)
print("Yosh:", person1.age)

Natija:

Ism: Dwight
Yosh: 43

Yuqoridagi misolda avtomatik yaratilgan memberwise initializerni ishlatib Person structining mos propertylariga qiymatlar berdik.

var person1 = Person(name: "Dwight", age: 43)

Bu yerda name ga Dwight, age ga esa 43 qiymati berildi.