Durumu Koruma
Coddy'nin Swift Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 19 / 57.
Değişmez, "bir bakiye hiçbir zaman negatif değildir" gibi, bir değer için her zaman geçerli olması gereken bir kuraldır. Bir tür, uygulamadan önce her değişikliği kontrol ederek değişmezlerini korur:
struct BankAccount {
private(set) var balance = 0
mutating func withdraw(_ amount: Int) -> Bool {
guard amount > 0, amount <= balance else { return false }
balance -= amount
return true
}
mutating func deposit(_ amount: Int) {
guard amount > 0 else { return }
balance += amount
}
}
var acc = BankAccount()
acc.deposit(100)
print(acc.withdraw(150))
print(acc.withdraw(40))
print(acc.balance)Çıktı:
false
true
60Bir çağıranın bir değişikliğin neden reddedildiğini bilmesi gerektiğinde, metot false döndürmek yerine bir hata fırlatabilir. Hata türü, Error protokolüne uyan bir enum'dur:
enum TransferError: Error {
case invalidAmount
case insufficientFunds(missing: Int)
}
struct Account {
private(set) var balance: Int
mutating func withdraw(_ amount: Int) throws {
guard amount > 0 else { throw TransferError.invalidAmount }
guard amount <= balance else { throw TransferError.insufficientFunds(missing: amount - balance) }
balance -= amount
}
}
var acc = Account(balance: 30)
do {
try acc.withdraw(50)
} catch TransferError.insufficientFunds(let missing) {
print("missing \(missing)")
} catch {
print("other error")
}Çıktı:
missing 20Korumalı verilerdeki her değişikliği, bu veriyi denetleyen yöntemlerin içinde tutun. Özellik dışarıdan ayarlanabilir olsaydı, herhangi bir kod satırı tür bunu fark etmeden kuralı ihlal edebilirdi:
struct Temperature {
private(set) var kelvin: Double // >= 0 kalmalı
mutating func cool(by amount: Double) {
kelvin = max(0, kelvin - amount) // onu düşürmenin tek yolu
}
}Birden fazla özelliği değiştiren bir işlem, işlem yarıda başarısız olsa bile bunları tutarlı bırakmalıdır. Önce her şeyi kontrol edin, ardından durumu değiştirin:
struct Inventory {
private(set) var stock: [String: Int] = ["tea": 2, "jam": 1]
mutating func sell(_ items: [String]) -> Bool {
var needed: [String: Int] = [:]
for i in items { needed[i, default: 0] += 1 }
for (item, n) in needed where (stock[item] ?? 0) < n { return false }
for (item, n) in needed { stock[item]! -= n }
return true
}
}
var inv = Inventory()
print(inv.sell(["tea", "jam", "jam"]))
print(inv.stock["tea"]!)
print(inv.sell(["tea", "jam"]))
print(inv.stock["tea"]!)Çıktı:
false
2
true
1Görev
KolaySeats struct'ını tamamla; bu struct, capacity sayıda koltuğu olan bir gösteri için bilet satar. sold, private(set) olarak tanımlıdır. buy(_:), 1'in altındaki bir sayı için TicketError.invalidCount, boş koltuk kalmadığında TicketError.soldOut ve istenenden daha az koltuk kaldığında TicketError.notEnough(left:) hatalarını verir; aksi takdirde biletleri sold değerine ekler.
Sağlanan kod, kapasiteyi ve her satırda bir istenen bilet sayısını okur. Her biri için sold 3, left 7, invalid count, sold out veya only 2 left yazdırır.
Kodun TicketError.swift ve Seats.swift dosyalarına yazılmalıdır. main.swift, sağlanan giriş/çıkış kodunu içerir ve düzenlenemez.
Kendin dene
// Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
var input: [String] = []
while let line = readLine() { input.append(line) }
var seats = Seats(capacity: Int(input[0])!)
for line in input.dropFirst() {
let n = Int(line)!
do {
try seats.buy(n)
print("sold \(n), left \(seats.capacity - seats.sold)")
} catch TicketError.invalidCount {
print("invalid count")
} catch TicketError.soldOut {
print("sold out")
} catch TicketError.notEnough(let left) {
print("only \(left) left")
} catch {
print("unexpected")
}
}
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