Structs en Swift: value semantics y cómo funciona la copia implícita

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.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP