Menu
Coddy logo textTech

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:

2

Eine 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-Konstante

Methoden, 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
3

Eine 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:

0
challenge icon

Aufgabe

Einfach

Vervollstä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())
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Swift-Playground