Başarısız Olabilen Başlatıcılar
Coddy'nin Swift Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 20 / 57.
Bazı değerler her girdiden oluşturulamaz. Başarısız olabilen başlatıcı (failable initializer) olarak adlandırılan ve init? şeklinde yazılan başlatıcı, girdi geçersiz olduğunda bir örnek yerine nil döndürür; böylece hiçbir geçersiz örnek var olamaz:
struct Percentage {
let value: Int
init?(_ value: Int) {
guard value >= 0, value <= 100 else { return nil }
self.value = value
}
}
print(Percentage(42)?.value ?? -1)
print(Percentage(150)?.value ?? -1)Çıktı:
42
-1Başarısız olabilen bir başlatıcının sonucu optional bir değerdir; bu nedenle çağıran taraf, genellikle if let veya guard let kullanarak bu değeri açmalıdır:
struct Email {
let address: String
init?(_ text: String) {
let parts = text.split(separator: "@")
guard parts.count == 2, parts[1].contains(".") else { return nil }
address = text.lowercased()
}
}
for text in ["Ada@Mail.com", "not-an-email"] {
if let email = Email(text) {
print("valid: \(email.address)")
} else {
print("invalid: \(text)")
}
}Çıktı:
valid: ada@mail.com
invalid: not-an-emailSwift'in kendi türleri de aynı fikri kullanır: Int("42") ve Double("x") başarısız olabilen başlatıcılardır ve bir enum'un init(rawValue:) başlatıcısı da öyledir. Başarısız olabilen bir başlatıcı bunları çağırabilir ve başarısızlığı aktarabilir:
struct Coordinate {
let lat: Double
let lon: Double
init?(text: String) {
let parts = text.split(separator: ",")
guard parts.count == 2,
let lat = Double(parts[0]), let lon = Double(parts[1]),
abs(lat) <= 90, abs(lon) <= 180 else { return nil }
self.lat = lat
self.lon = lon
}
}
print(Coordinate(text: "51.5,-0.1") != nil)
print(Coordinate(text: "95,10") != nil)Çıktı:
true
falseEksik bir değerin yeterli bilgi olduğu durumlarda init? kullanın. Çağıranın hangi kuralın ihlal edildiğini öğrenmesi gerektiğinde hata fırlatan bir başlatıcı olan init(...) throws kullanın:
struct Username {
let text: String
init(_ text: String) throws {
guard text.count >= 3 else { throw NameError.tooShort }
guard text.allSatisfy({ $0.isLetter }) else { throw NameError.badCharacters }
self.text = text
}
}Görev
KolayBir rengi 0'dan 255'e kadar red, green ve blue olarak saklayan Rgb yapısını tamamla. Hata verebilen başlatıcısı init?(hex:), #FF8000 gibi metinleri okur: Metin, # işaretinin ardından tam olarak altı onaltılık basamak gelmediği sürece nil döndürür. Her ikili için Int(text, radix: 16) kullan. rgb(255, 128, 0) döndüren hesaplanmış bir label ekle.
Sağlanan kod her satırda bir renk okur ve etiketi ya da invalid: text yazdırır.
Kodun Rgb.swift dosyasına yazılmalı. main.swift sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
// Sağlanan giriş/çıkış kodu: olduğu gibi bırakın
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
if let color = Rgb(hex: line) {
print(color.label)
} else {
print("invalid: \(line)")
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıfları TanımlamaMetotlar ve selfBaşlatıcılarSınıflar ReferanstırTekrar - Kütüphane Kartı4Kapsülleme
Erişim DenetimiDışarıdan Salt OkunurDurumu KorumaBaşarısız Olabilen BaşlatıcılarTekrar - Banka Hesabı7Polimorfizm ve Generic'ler
PolimorfizmTür DönüşümüGeneric FonksiyonlarGeneric TürlerTekrar - Şekil Hesaplayıcı2Struct Yapıları ve Değer Türleri
Struct YapılarıDeğer SemantiğiDeğiştirici MetotlarStruct mı Class mıTekrar - Envanter Öğesi5Kalıtım
Alt sınıflarMetotları Geçersiz KılmaBaşlatıcılar ve superfinal ve HiyerarşilerTekrar - Çalışan Hiyerarşisi11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç AlmaKendi başına pratik yap: Swift playground