Metodi mutanti
Fa parte della sezione Programmazione orientata agli oggetti del percorso Swift di Coddy. Lezione 9 di 57.
Un metodo di una struct che modifica una proprietà deve essere contrassegnato con mutating. Senza la parola chiave, il metodo non viene compilato, perché i metodi di un tipo valore considerano self costante:
struct Counter {
var count = 0
mutating func increment() {
count += 1
}
}
var c = Counter()
c.increment()
c.increment()
print(c.count)Output:
2Un metodo mutante può essere chiamato solo su una var. Su una costante let la chiamata non viene compilata, perché l'intero valore è fisso:
var a = Counter()
a.increment() // fine
let b = Counter()
// b.increment() // error: b is a let constantI metodi che si limitano a leggere le proprietà non le modificano e funzionano anche con le costanti. Un buon design concentra le modifiche in pochi metodi che modificano i dati:
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)Output:
8
3Un metodo mutante può sostituire interamente self, il che è utile per reimpostare un valore:
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)Output:
0Sfida
FacileCompleta la struct Wallet. add(_:) e spend(_:) sono mutating: spend sottrae solo quando rimane denaro a sufficienza e restituisce se lo ha fatto. report() non è mutating e restituisce balance 40.
Il codice fornito legge i comandi +n e -n, li applica a un unico wallet var, stampa denied in caso di spesa rifiutata e infine stampa report().
Il tuo codice va in Wallet.swift. main.swift contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
// Codice di input/output fornito: lascialo così com'è
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())
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiMetodi e selfInizializzatoriLe classi sono riferimentiRiepilogo - Tessera della biblioteca4Incapsulamento
Controllo degli accessiSola lettura dall’esternoProteggere lo statoInizializzatori che possono fallireRiepilogo - Conto bancario7Polimorfismo e tipi generici
PolimorfismoCasting dei tipiFunzioni genericheTipi genericiRipasso - Calcolatore di forme2Struct e tipi valore
Le structSemantica dei valoriMetodi mutantiStruct o classeRiepilogo - Articolo di inventario5Ereditarietà
SottoclassiSovrascrivere i metodiInizializzatori e superfinal e gerarchieRiepilogo - Gerarchia dei dipendenti8Protocolli standard
CustomStringConvertibleEquatableComparableHashableRiepilogo - Ordinamento personalizzato11Progetto: Gestione della biblioteca
Libri e utentiPrestito dei libriEsercitati da solo: Playground Swift