Attention: les termes du profane à venir.
Cette explication n'est pas rigoureusement correcte au niveau du code le plus précis. Cependant, il a été revu par un gars qui travaille réellement sur Swift et il a dit que c'était assez bon comme explication de base.
Je veux donc essayer de répondre simplement et directement à la question du «pourquoi».
Pour être précis: pourquoi devons-nous marquer les fonctions de structure comme mutating
lorsque nous pouvons changer les paramètres de structure sans modifier les mots-clés?
Donc, dans son ensemble, cela a beaucoup à voir avec la philosophie qui maintient Swift rapide.
Vous pourriez en quelque sorte penser au problème de la gestion des adresses physiques réelles. Lorsque vous changez d'adresse, s'il y a beaucoup de personnes qui ont votre adresse actuelle, vous devez les informer toutes que vous avez déménagé. Mais si personne n'a votre adresse actuelle, vous pouvez simplement vous déplacer où vous voulez, et personne n'a besoin de savoir.
Dans cette situation, Swift est un peu comme le bureau de poste. Si beaucoup de personnes avec beaucoup de contacts se déplacent beaucoup, cela a des frais généraux très élevés. Il doit payer un grand nombre de personnes pour gérer toutes ces notifications, et le processus prend beaucoup de temps et d'efforts. C'est pourquoi l'état idéal de Swift est que chacun dans sa ville ait le moins de contacts possible. Ensuite, il n'a pas besoin d'un gros personnel pour gérer les changements d'adresse, et il peut faire tout le reste plus rapidement et mieux.
C'est aussi pourquoi les gens de Swift raffolent tous des types de valeur par rapport aux types de référence. Par nature, les types de référence accumulent des "contacts" partout, et les types de valeur n'ont généralement pas besoin de plus d'un couple. Les types de valeur sont "Swift" -er.
Revenons donc à la petite image: structs
. Les structures sont un gros problème dans Swift car elles peuvent faire la plupart des choses que les objets peuvent faire, mais ce sont des types de valeur.
Continuons l'analogie de l'adresse physique en imaginant une misterStruct
qui habite someObjectVille
. L'analogie est un peu déconcertée ici, mais je pense qu'elle est toujours utile.
Donc, pour modéliser la modification d'une variable sur un struct
, disons misterStruct
a les cheveux verts, et obtient un ordre de passer aux cheveux bleus. L'analogie est déconcertée, comme je l'ai dit, mais ce qui se passe en quelque sorte, c'est qu'au lieu de changer misterStruct
de cheveux, la personne âgée déménage et une nouvelle personne aux cheveux bleus entre, et cette nouvelle personne commence à s'appeler misterStruct
. Personne n'a besoin de recevoir une notification de changement d'adresse, mais si quelqu'un regarde cette adresse, il verra un gars aux cheveux bleus.
Modélisons maintenant ce qui se passe lorsque vous appelez une fonction sur un fichier struct
. Dans ce cas, c'est comme misterStruct
obtenir une commande telle que changeYourHairBlue()
. Alors le bureau de poste donne l'instruction misterStruct
"d'aller changer vos cheveux en bleu et me dire quand vous avez terminé."
S'il suit la même routine qu'avant, s'il fait ce qu'il a fait lorsque la variable a été modifiée directement, ce qu'il misterStruct
va faire est de quitter sa propre maison et d'appeler une nouvelle personne aux cheveux bleus. Mais c'est ça le problème.
L'ordre était "allez changer vos cheveux en bleu et dites-moi quand vous avez terminé", mais c'est le gars vert qui a reçu cet ordre. Une fois que le gars bleu a emménagé, une notification "travail terminé" doit encore être renvoyée. Mais le gars bleu n'en sait rien.
[Pour vraiment contrarier cette analogie, quelque chose d'horrible, ce qui est techniquement arrivé à un gars aux cheveux verts, c'est qu'après son déménagement, il s'est immédiatement suicidé. Donc , il ne peut en aviser quiconque que la tâche est terminée , soit! ]
Pour éviter ce problème, dans des cas comme celui-ci uniquement , Swift doit se rendre directement à la maison à cette adresse et changer les cheveux de l'habitant actuel . C'est un processus complètement différent de celui d'envoyer simplement un nouveau gars.
Et c'est pourquoi Swift veut que nous utilisions le mutating
mot - clé!
Le résultat final ressemble à tout ce qui doit faire référence à la structure: l'habitant de la maison a maintenant les cheveux bleus. Mais les processus pour y parvenir sont en fait complètement différents. On dirait que ça fait la même chose, mais ça fait une chose très différente. Cela fait quelque chose que les structures Swift en général ne font jamais.
Donc, pour donner un peu d'aide au pauvre compilateur, et ne pas l'obliger à déterminer si une fonction mute struct
ou non, seule, pour chaque fonction struct, on nous demande d'avoir pitié et d'utiliser le mutating
mot - clé.
En substance, pour aider Swift à rester rapide, nous devons tous faire notre part. :)
ÉDITER:
Hey mec / dudette qui m'a refusé, je viens de réécrire complètement ma réponse. Si cela vous convient mieux, supprimerez-vous le vote défavorable?