In Swift, le strutture (struct) sono, per impostazione predefinita, value type: durante la copia di un'istanza di una struttura, viene creata una copia indipendente. Tuttavia, a differenza delle classi, i metodi della struttura non possono modificare self e le sue proprietà senza il permesso esplicito del compilatore. Nelle versioni precedenti dei linguaggi C e C++, le strutture erano sempre modificabili, il che portava a effetti collaterali imprevisti. Swift aumenta la sicurezza richiedendo di contrassegnare esplicitamente i metodi che modificano lo stato della struttura con la parola chiave mutating.
Il problema si presenta se è necessario un metodo per modificare le proprietà della struttura, ma è dichiarato come normale, e il compilatore non consente di farlo. Senza mutating non è possibile modificare self o le sue proprietà.
La soluzione consiste nel dichiarare tali metodi utilizzando la parola chiave mutating, il che dà al compilatore il segnale di consentire la modifica di self e delle proprietà annidate.
Esempio di codice:
struct Counter { var value = 0 mutating func increment() { value += 1 } // Questo metodo NON verrà compilato se si rimuove mutating } var counter = Counter() counter.increment() // value è diventato 1
Caratteristiche principali:
1. È possibile chiamare metodi mutating su una struttura dichiarata tramite let?
No, non è possibile. I valori costanti let delle strutture non possono essere modificati, anche con metodi mutating.
let counter = Counter() counter.increment() // Errore di compilazione
2. Possono le proprietà annidate di una classe all'interno di una struttura essere modificate all'interno di un metodo mutating della struttura?
Sì, se la proprietà della struttura è un reference type (ad esempio, una classe), le sue proprietà interne possono essere modificate anche senza mutating, ma l'intera struttura può essere modificata solo tramite mutating.
class State { var value = 0 } struct Wrapper { var state = State() mutating func change() { state.value += 1 } }
3. È possibile modificare solo una computed property all'interno di un metodo senza mutating?
No. Se la computed property ha un set, la modifica del suo valore all'interno del metodo richiede comunque mutating.
In un progetto è stato implementato un semplice contatore con una struttura, ma lo sviluppatore ha dimenticato di contrassegnare il metodo come mutating. I test non passano perché il valore non cambia.
Pro:
Contro:
I metodi nella struttura sono contrassegnati come mutating, i test passano e le modifiche vengono aggiornate correttamente. Il codice è chiaro a tutti i membri del team.
Pro:
Contro: