En Swift, las estructuras (struct) son, por defecto, tipos de valor: al copiar una instancia de una estructura, se crea una copia independiente. Sin embargo, a diferencia de las clases, los métodos de una estructura no pueden modificar self y sus propiedades sin el consentimiento explícito del compilador. En versiones anteriores de los lenguajes C y C++, las estructuras eran siempre mutables, lo que podía llevar a efectos secundarios inesperados. Swift aumenta la seguridad al exigir que se marquen explícitamente los métodos que cambian el estado de la estructura con la palabra clave mutating.
El problema surge si un método necesita cambiar las propiedades de la estructura, pero se declara como regular y el compilador no permite hacerlo. Sin mutating, no puedes cambiar self ni sus propiedades.
La solución es declarar tales métodos con la palabra clave mutating, lo que le da al compilador la señal de permitir el cambio de self y de las propiedades anidadas.
Ejemplo de código:
struct Counter { var value = 0 mutating func increment() { value += 1 } // Este método NO se compilará si se quita mutating } var counter = Counter() counter.increment() // value se volvió 1
Características clave:
1. ¿Se pueden llamar métodos mutating en una estructura declarada con let?
No, no se puede. Los valores constantes let de las estructuras no pueden ser cambiados, ni siquiera con métodos mutating.
let counter = Counter() counter.increment() // Error de compilación
2. ¿Pueden las propiedades anidadas de una clase dentro de una estructura cambiarse dentro de un método mutating de una estructura?
Sí, si la propiedad de la estructura es un tipo de referencia (por ejemplo, una clase), sus propiedades internas se pueden cambiar incluso sin mutating, pero la estructura en su totalidad solo se puede cambiar a través de mutating.
class State { var value = 0 } struct Wrapper { var state = State() mutating func change() { state.value += 1 } }
3. ¿Se puede cambiar solo una propiedad computada dentro de un método sin mutating?
No. Si la propiedad computada tiene un set, entonces cambiar su valor dentro de un método aún requiere mutating.
En el proyecto se implementó un contador simple usando una estructura, pero el desarrollador olvidó marcar el método como mutating. Las pruebas no pasan porque el valor no cambia.
Ventajas:
Desventajas:
Los métodos en la estructura están marcados como mutating, las pruebas pasan, los cambios se actualizan correctamente. El código es claro para todos los miembros del equipo.
Ventajas:
Desventajas: