ProgrammazioneSviluppatore iOS di livello intermedio

Come funziona il meccanismo delle funzioni mutating nelle strutture Swift e perché è necessario per modificare lo stato dei value types? Quali limiti pone i metodi mutating?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

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:

  • Solo i metodi con mutating possono modificare self e le sue proprietà.
  • Non è possibile chiamare metodi mutating su costanti (istanze let).
  • Nelle strutture, self può essere completamente sostituito all'interno di un metodo mutating.

Domande trabocchetto.

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.

Errori comuni e anti-pattern

  • Dimenticare di dichiarare il metodo come mutating, il che impedisce la compilazione delle modifiche alle proprietà.
  • Utilizzare strutture nei casi in cui è frequente la necessità di modificare lo stato: in questi casi è meglio utilizzare una classe.
  • Ignorare le peculiarità della copia delle strutture durante le modifiche.

Esempio della vita reale

Caso negativo

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:

  • Funzionalità implementata rapidamente.

Contro:

  • L'errore non è chiaro per lo sviluppatore, si perde tempo a chiarire la causa.
  • Le modifiche non vengono registrate, creando confusione nel codice.

Caso positivo

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:

  • Tipizzazione rigorosa e comportamento prevedibile.
  • Alta resilienza agli errori.

Contro:

  • Si aggiunge l'obbligo di ricordare mutating nella firma.