Menu
Coddy logo textTech

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:

2

Un 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 constant

I 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
3

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

0
challenge icon

Sfida

Facile

Completa 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())
quiz iconMettiti alla prova

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

Esercitati da solo: Playground Swift