Attenzione: i termini del profano sono avanti.
Questa spiegazione non è rigorosamente corretta al livello di codice più nitido. Tuttavia è stato recensito da un ragazzo che lavora su Swift e ha detto che è abbastanza buono come spiegazione di base.
Quindi voglio provare a rispondere in modo semplice e diretto alla domanda del "perché".
Per essere precisi: perché dobbiamo contrassegnare le funzioni struct come mutating
quando possiamo cambiare i parametri della struttura senza modificare le parole chiave?
Quindi, il quadro generale, ha molto a che fare con la filosofia che mantiene Swift veloce.
Potresti pensarlo come il problema della gestione degli indirizzi fisici effettivi. Quando cambi il tuo indirizzo, se ci sono molte persone che hanno il tuo attuale, devi avvisare tutti che ti sei trasferito. Ma se nessuno ha il tuo indirizzo attuale, puoi spostarti dove vuoi e nessuno deve saperlo.
In questa situazione, Swift è un po 'come l'ufficio postale. Se molte persone con molti contatti si muovono molto, il sovraccarico è davvero elevato. Deve pagare un grande staff di persone per gestire tutte quelle notifiche e il processo richiede molto tempo e fatica. Ecco perché lo stato ideale di Swift è che tutti nella sua città abbiano il minor numero di contatti possibile. Quindi non ha bisogno di un grande staff per gestire i cambiamenti di indirizzo e può fare tutto il resto più velocemente e meglio.
Questo è anche il motivo per cui Swift-folks è entusiasta dei tipi di valore rispetto ai tipi di riferimento. Per natura, i tipi di riferimento accumulano "contatti" ovunque e i tipi di valore di solito non hanno bisogno di più di un paio. I tipi di valore sono "Swift" -er.
Ma torniamo al piccolo immagine: structs
. Le strutture sono un grosso problema in Swift perché possono fare la maggior parte delle cose che gli oggetti possono fare, ma sono tipi di valore.
Continuiamo l'analogia dell'indirizzo fisico immaginando un misterStruct
che vive someObjectVille
. L'analogia è un po 'vinta qui, ma penso che sia ancora utile.
Quindi, per modellare la modifica di una variabile su a struct
, diciamo che misterStruct
ha i capelli verdi e ottiene un ordine per passare ai capelli blu. L'analogia viene vinta, come ho detto, ma più o meno quello che succede è che invece di cambiare misterStruct
i capelli, la persona anziana se ne va e una nuova persona con i capelli blu si avvicina, e quella nuova persona inizia a chiamarsi misterStruct
. Nessuno ha bisogno di ricevere una notifica di cambio di indirizzo, ma se qualcuno guarda quell'indirizzo, vedrà un ragazzo con i capelli blu.
Ora modelliamo cosa succede quando chiami una funzione su un file struct
. In questo caso, è come misterStruct
ricevere un ordine come changeYourHairBlue()
. Quindi l'ufficio postale fornisce le istruzioni per misterStruct
"vai a cambiarti i capelli in blu e dimmi quando hai finito".
Se sta seguendo la stessa routine di prima, se sta facendo quello che ha fatto quando la variabile è stata cambiata direttamente, quello misterStruct
che farà è uscire di casa sua e chiamare una nuova persona con i capelli blu. Ma questo è il problema.
L'ordine era "vai a cambiarti i capelli in blu e dimmi quando hai finito", ma è il ragazzo verde che ha ricevuto quell'ordine. Dopo che il ragazzo blu si è trasferito, una notifica di "completamento del lavoro" deve ancora essere rispedita. Ma il ragazzo blu non ne sa niente.
[Per risolvere davvero questa analogia con qualcosa di terribile, quello che tecnicamente è successo al ragazzo dai capelli verdi è stato che dopo essersi trasferito si è immediatamente suicidato. Quindi non può nemmeno avvisare nessuno che l'attività è stata completata ! ]
Per evitare questo problema, in casi come questo solo , Swift deve andare in direttamente a casa a quell'indirizzo e effettivamente cambiare i capelli del abitante corrente . Questo è un processo completamente diverso dal semplice invio di un nuovo ragazzo.
Ed è per questo che Swift vuole che usiamo la mutating
parola chiave!
Il risultato finale sembra lo stesso per tutto ciò che deve riferirsi alla struttura: l'abitante della casa ora ha i capelli blu. Ma i processi per ottenerlo sono in realtà completamente diversi. Sembra che stia facendo la stessa cosa, ma sta facendo una cosa molto diversa. Sta facendo una cosa che le strutture Swift in generale non fanno mai.
Quindi, per dare un piccolo aiuto al povero compilatore e non costringerlo a capire se una funzione muta struct
o meno, da sola, per ogni singola funzione struct, ci viene chiesto di avere pietà e di usare la mutating
parola chiave.
In sostanza, per aiutare Swift a rimanere veloce, dobbiamo tutti fare la nostra parte. :)
MODIFICARE:
Ehi amico / tizio che mi ha svalutato, ho appena riscritto completamente la mia risposta. Se ti sta meglio, rimuoverai il voto negativo?