Swift genera automáticamente un inicializador que acepta todos los stored properties como argumentos:
struct Punto {
var x: Double
var y: Double
func distanciaAlOrigen() -> Double {
(x*x + y*y).squareRoot()
}
}
let p = Punto(x: 3, y: 4) // memberwise init
print(p.distanciaAlOrigen()) // 5.0
Semántica de valor: la copia es independiente
var a = Punto(x: 1, y: 2)
var b = a // copia
b.x = 99
print(a.x) // 1 (a no cambio)
print(b.x) // 99
mutating methods
Para modificar properties dentro de un método de struct hay que marcarlo como mutating. Esto es necesario porque, al ser tipos por valor, el compilador necesita saber cuándo se va a modificar la instancia:
struct Contador {
private(set) var valor = 0
mutating func incrementar() { valor += 1 }
mutating func reset() { valor = 0 }
}
var c = Contador()
c.incrementar(); c.incrementar()
print(c.valor) // 2
c.reset()
print(c.valor) // 0
Copy-on-write en la práctica
var arr1 = [1, 2, 3, 4, 5]
var arr2 = arr1 // no se copia el buffer todavia
arr2.append(6) // ahora si se copia
print(arr1.count) // 5 (sin cambios)
print(arr2.count) // 6
Cuándo usar struct
Apple recomienda structs por defecto. Usa struct cuando: los datos deban copiarse al asignarse o pasarse como argumento, cuando no necesites herencia de implementación, o cuando el tipo modele un valor simple (coordenada, rango, color). Usa class cuando necesites identidad de objeto (===), ciclo de vida con deinit, o herencia de Objective-C.
