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:
2Um 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 letMé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
3Um 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:
0Desafio
FácilComplete 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())
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
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesMétodos e selfInicializadoresClasses são ReferênciasRevisão - Cartão da Biblioteca4Encapsulamento
Controle de AcessoSomente Leitura ExternaProtegendo o EstadoInicializadores que Podem FalharRevisão - Conta Bancária7Polimorfismo e Genéricos
PolimorfismoConversão de TiposFunções GenéricasTipos GenéricosRevisão - Calculadora de Formas2Structs e Tipos de Valor
StructsSemântica de ValorMétodos MutáveisStruct ou ClasseRecapitulação - Item de Inventário5Herança
SubclassesSobrescrita de métodosInicializadores e superfinal e hierarquiasRecapitulação - Hierarquia de funcionários8Protocolos Padrão
CustomStringConvertibleEquatableComparableHashableRecapitulação - Ordenação Personalizada11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Playground de Swift