Verändernde Methoden
Teil des Abschnitts Objektorientierte Programmierung der Swift-Journey von Coddy. Lektion 9 von 57.
Eine Struct-Methode, die eine Eigenschaft ändert, muss als mutating markiert werden. Ohne dieses Schlüsselwort wird die Methode nicht kompiliert, da Methoden eines Werttyps self als konstant behandeln:
struct Counter {
var count = 0
mutating func increment() {
count += 1
}
}
var c = Counter()
c.increment()
c.increment()
print(c.count)Ausgabe:
2Eine mutierende Methode kann nur auf einer var-Variable aufgerufen werden. Bei einer let-Konstanten wird der Aufruf nicht kompiliert, weil der gesamte Wert unveränderlich ist:
var a = Counter()
a.increment() // in Ordnung
let b = Counter()
// b.increment() // Fehler: b ist eine let-KonstanteMethoden, die nur Eigenschaften lesen, bleiben nicht-mutarierend und funktionieren auch mit Konstanten. Ein gutes Design hält Änderungen in wenigen mutierenden Methoden:
struct Stack {
var items: [Int] = []
mutating func push(_ x: Int) { items.append(x) }
mutating func pop() -> Int? { items.popLast() }
func peek() -> Int? { items.last }
}
var s = Stack()
s.push(3)
s.push(8)
print(s.pop() ?? -1)
print(s.peek() ?? -1)Ausgabe:
8
3Eine mutierende Methode kann self vollständig ersetzen, was beim Zurücksetzen eines Werts praktisch ist:
struct Score {
var points = 0
var bonus = 0
mutating func reset() {
self = Score()
}
}
var s = Score(points: 10, bonus: 3)
s.reset()
print(s.points + s.bonus)Ausgabe:
0Aufgabe
EinfachVervollständige die Struktur Wallet. add(_:) und spend(_:) sind mutierend: spend subtrahiert nur, wenn noch genügend Geld vorhanden ist, und gibt zurück, ob dies der Fall war. report() ist nicht mutierend und gibt balance 40 zurück.
Der bereitgestellte Code liest die Befehle +n und -n, wendet sie auf eine einzelne var-Wallet an, gibt bei einer abgelehnten Ausgabe denied aus und gibt schließlich report() aus.
Dein Code gehört in Wallet.swift. main.swift enthält den bereitgestellten Eingabe-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
// Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
var input: [String] = []
while let line = readLine() { input.append(line) }
var wallet = Wallet()
for cmd in input {
let amount = Int(cmd.dropFirst())!
if cmd.hasPrefix("+") {
wallet.add(amount)
} else if !wallet.spend(amount) {
print("denied")
}
}
print(wallet.report())
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenMethoden und selfInitialisiererKlassen sind ReferenzenRückblick – Bibliotheksausweis4Kapselung
ZugriffskontrolleVon außen schreibgeschütztZustand schützenFehlschlagende InitialisiererRückblick – Bankkonto7Polymorphismus und Generika
PolymorphismusTypumwandlungGenerische FunktionenGenerische TypenZusammenfassung – Shape-Rechner2Strukturen und Werttypen
StrukturenWertsemantikVerändernde MethodenStruktur oder KlasseZusammenfassung – Inventarelement5Vererbung
UnterklassenMethoden überschreibenInitialisierer und superfinal und HierarchienRückblick – Mitarbeiterhierarchie8Standardprotokolle
CustomStringConvertibleEquatableComparableHashableRückblick – Benutzerdefiniertes Sortieren11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Swift-Playground