Métodos mutables
Parte de la sección Programación orientada a objetos del Journey de Swift de Coddy. Lección 9 de 57.
Un método de una estructura que cambia una propiedad debe marcarse como mutating. Sin esta palabra clave, el método no se compila, porque los métodos de un tipo de valor tratan self como una constante:
struct Counter {
var count = 0
mutating func increment() {
count += 1
}
}
var c = Counter()
c.increment()
c.increment()
print(c.count)Salida:
2Un método mutante solo se puede llamar en una var. En una constante let, la llamada no se compila, porque todo el valor es fijo:
var a = Counter()
a.increment() // bien
let b = Counter()
// b.increment() // error: b es una constante letLos métodos que solo leen propiedades no producen mutaciones y también funcionan con constantes. Un buen diseño mantiene los cambios en unos pocos métodos mutantes:
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)Salida:
8
3Un método mutador puede reemplazar self por completo, lo cual resulta útil para restablecer un 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)Salida:
0Desafío
FácilCompleta la estructura Wallet. add(_:) y spend(_:) son mutantes: spend resta solo cuando queda suficiente dinero y devuelve si lo hizo. report() no es mutante y devuelve balance 40.
El código proporcionado lee los comandos +n y -n, los aplica a una única var wallet, imprime denied cuando se rechaza un gasto y, finalmente, imprime report().
Tu código va en Wallet.swift. main.swift contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
// Código de entrada/salida suministrado: déjalo tal cual
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 lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesMétodos y selfInicializadoresLas clases son referenciasRepaso: tarjeta de biblioteca4Encapsulación
Control de accesoSolo lectura desde fueraProtección del estadoInicializadores que pueden fallarRepaso - Cuenta bancaria7Polimorfismo y genéricos
PolimorfismoConversión de tiposFunciones genéricasTipos genéricosRepaso - Calculadora de formas2Structs y tipos por valor
StructsSemántica de valoresMétodos mutablesStruct o claseRepaso - elemento del inventario5Herencia
SubclasesSobrescritura de métodosInicializadores y superfinal y jerarquíasRepaso: jerarquía de empleados8Protocolos estándar
CustomStringConvertibleEquatableComparableHashableRepaso - Ordenamiento personalizado11Proyecto: Gestión de bibliotecas
Libros y miembrosPréstamo de librosPractica por tu cuenta: Playground de Swift