Precaución: términos legos por delante.
Esta explicación no es rigurosamente correcta en el nivel de código más esencial. Sin embargo, ha sido revisado por un tipo que realmente trabaja en Swift y dijo que es lo suficientemente bueno como explicación básica.
Así que quiero intentar responder de forma simple y directa a la pregunta de "por qué".
Para ser precisos: ¿por qué tenemos que marcar las funciones de estructura mutating
cuando podemos cambiar los parámetros de estructura sin modificar las palabras clave?
Entonces, en general, tiene mucho que ver con la filosofía que mantiene a Swift veloz.
Podría pensar en ello como el problema de administrar direcciones físicas reales. Cuando cambie su dirección, si hay muchas personas que tienen la actual, debe notificarles a todas que se ha mudado. Pero si nadie tiene su dirección actual, simplemente puede mudarse a donde quiera, y nadie necesita saberlo.
En esta situación, Swift es como la oficina de correos. Si muchas personas con muchos contactos se mueven mucho, hay una sobrecarga muy alta. Tiene que pagar una gran cantidad de personas para manejar todas esas notificaciones, y el proceso requiere mucho tiempo y esfuerzo. Es por eso que el estado ideal de Swift es que todos en su ciudad tengan la menor cantidad de contactos posible. Entonces no necesita un gran personal para manejar los cambios de dirección y puede hacer todo lo demás más rápido y mejor.
Esta es también la razón por la que la gente de Swift está entusiasmada con los tipos de valor frente a los tipos de referencia. Por naturaleza, los tipos de referencia acumulan "contactos" por todas partes, y los tipos de valor no suelen necesitar más de un par. Los tipos de valor son "Swift" -er.
Así que de vuelta a la imagen pequeña: structs
. Las estructuras son un gran problema en Swift porque pueden hacer la mayoría de las cosas que pueden hacer los objetos, pero son tipos de valor.
Continuemos con la analogía de la dirección física imaginando un misterStruct
que vive en someObjectVille
. La analogía se torna un poco complicada aquí, pero creo que todavía es útil.
Entonces, para modelar el cambio de una variable en a struct
, digamos que misterStruct
tiene cabello verde y recibe una orden para cambiar a cabello azul. La analogía se torna torpe, como dije, pero más o menos lo que sucede es que en lugar de cambiarse misterStruct
el cabello, la persona mayor se muda y entra una nueva persona con cabello azul , y esa nueva persona comienza a llamarse a sí misma misterStruct
. Nadie necesita recibir una notificación de cambio de dirección, pero si alguien mira esa dirección, verá a un tipo con el pelo azul.
Ahora modelemos lo que sucede cuando llamas a una función en a struct
. En este caso, es como misterStruct
recibir un pedido como changeYourHairBlue()
. Entonces, la oficina de correos da la instrucción de misterStruct
"ir a cambiarte el cabello a azul y decirme cuando hayas terminado".
Si sigue la misma rutina que antes, si está haciendo lo que hizo cuando se cambió la variable directamente, lo misterStruct
que hará es mudarse de su propia casa y llamar a una nueva persona con cabello azul. Pero ese es el problema.
La orden era "ve a cambiarte el pelo a azul y dime cuando termines", pero es el chico verde quien recibió esa orden. Después de que el chico azul se mude, aún debe enviarse una notificación de "trabajo completado". Pero el chico azul no sabe nada al respecto.
[Para realmente pensar en esta analogía algo horrible, lo que técnicamente le sucedió al chico de cabello verde fue que después de mudarse, inmediatamente se suicidó. ¡Así que tampoco puede notificar a nadie que la tarea está completa ! ]
Para evitar este problema, en casos como éste solamente , Swift tiene que ir directamente a la casa en esa dirección y en realidad cambiar el pelo de la fábrica actual . Ese es un proceso completamente diferente a simplemente enviar a un chico nuevo.
¡Y es por eso que Swift quiere que usemos la mutating
palabra clave!
El resultado final se ve igual para cualquier cosa que tenga que referirse a la estructura: el habitante de la casa ahora tiene el pelo azul. Pero los procesos para lograrlo son en realidad completamente diferentes. Parece que está haciendo lo mismo, pero está haciendo algo muy diferente. Está haciendo algo que las estructuras Swift en general nunca hacen.
Entonces, para darle un poco de ayuda al compilador pobre, y no hacer que tenga que averiguar si una función muta struct
o no, por sí sola, para cada función de estructura, se nos pide que tengamos lástima y usemos la mutating
palabra clave.
En esencia, para ayudar a Swift a mantenerse veloz, todos debemos hacer nuestra parte. :)
EDITAR:
Hola amigo / dudette que me votó negativamente, simplemente reescribí completamente mi respuesta. Si le sienta mejor, ¿eliminará el voto negativo?