Menu
Coddy logo textTech

Métodos Mutáveis

Parte da seção Programação Orientada a Objetos do Journey de Swift da Coddy. Lição 9 de 57.

Um método de uma struct que altera uma propriedade deve ser marcado como mutating. Sem essa palavra-chave, o método não compila, porque os métodos de um tipo por valor tratam self como constante:

struct Counter {
    var count = 0

    mutating func increment() {
        count += 1
    }
}

var c = Counter()
c.increment()
c.increment()
print(c.count)

Saída:

2

Um método mutável só pode ser chamado em uma var. Em uma constante let, a chamada não compila, porque o valor inteiro é fixo:

var a = Counter()
a.increment()        // ok

let b = Counter()
// b.increment()     // erro: b é uma constante let

Métodos que apenas leem propriedades permanecem não mutáveis e também funcionam com constantes. Um bom design mantém as alterações concentradas em poucos métodos mutáveis:

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)

Saída:

8
3

Um método mutável pode substituir self inteiramente, o que é útil para redefinir um valor:

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)

Saída:

0
challenge icon

Desafio

Fácil

Complete a struct Wallet. add(_:) e spend(_:) são mutantes: spend subtrai somente quando há dinheiro suficiente e retorna se conseguiu fazê-lo. report() não é mutante e retorna balance 40.

O código fornecido lê os comandos +n e -n, aplica-os a uma única carteira var, imprime denied quando um gasto é recusado e, por fim, imprime report().

Seu código deve estar em Wallet.swift. main.swift contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

// Código de entrada/saída fornecido: mantenha-o como está
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 seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Playground de Swift