Осторожно: условия непрофессионала впереди.
Это объяснение не совсем корректно на самом мелком уровне кода. Однако он был рассмотрен парнем, который действительно работает над Swift, и сказал, что это достаточно хорошо в качестве основного объяснения.
Поэтому я хочу попытаться просто и прямо ответить на вопрос «почему».
Чтобы быть точным: почему мы должны отмечать структурные функции, mutating
когда мы можем изменять параметры структуры без каких-либо модифицирующих ключевых слов?
Итак, большая картина, это во многом связано с философией, которая поддерживает Swift Swift .
Вы могли бы думать об этом как о проблеме управления реальными физическими адресами. Когда вы меняете свой адрес, если у многих людей есть ваш текущий, вы должны уведомить их всех о том, что вы переехали. Но если ни у кого нет вашего текущего адреса, вы можете просто переехать куда хотите, и никому не нужно знать.
В этой ситуации Swift чем-то похож на почтовое отделение. Если много людей с большим количеством контактов много перемещаются, это очень дорого обходится. За обработку всех этих уведомлений приходится платить большому количеству людей, а процесс отнимает много времени и усилий. Вот почему идеальное состояние Swift - чтобы у всех в городе было как можно меньше контактов. Тогда ему не понадобится большой персонал для обработки изменений адреса, и он сможет делать все остальное быстрее и лучше.
Вот почему все Swift-люди бредят о типах значений и ссылочных типах. По своей природе ссылочные типы создают «контакты» повсюду, а типам значений обычно не требуется больше пары. Типы значений - "Swift" -er.
Итак , вернемся к маленькой картинке: structs
. Структуры имеют большое значение в Swift, потому что они могут делать большинство вещей, которые могут делать объекты, но они являются типами значений.
Давайте продолжим аналогию с физическим адресом, представив, misterStruct
что живет в someObjectVille
. Аналогия здесь немного запутана, но я думаю, что она все же полезна.
Итак, для модели, изменяющей переменную на a struct
, допустим, у misterStruct
нее зеленые волосы, и она получает команду переключиться на синие волосы. Как я уже сказал, аналогия оказывается неудачной, но происходит нечто вроде того, что вместо того, чтобы менять misterStruct
прическу, старый человек уезжает, а новый человек с голубыми волосами входит в комнату, и этот новый человек начинает называть себя misterStruct
. Никому не нужно получать уведомление о смене адреса, но если кто-нибудь посмотрит на этот адрес, он увидит парня с синими волосами.
Теперь давайте смоделируем, что происходит, когда вы вызываете функцию в struct
. В данном случае это как misterStruct
получить заказ типа changeYourHairBlue()
. Итак, почтовое отделение доставляет инструкцию: misterStruct
«Иди смени свои волосы на синие и скажи мне, когда закончишь».
Если он следует той же рутине, что и раньше, если он делает то, что делал, когда переменная была изменена напрямую, то misterStruct
он переедет из собственного дома и вызовет нового человека с синими волосами. Но вот в чем проблема.
Приказ был: «Иди, смени свои волосы на синие и скажи мне, когда закончишь», но этот приказ получил зеленый парень. После того, как синий парень въезжает, уведомление о завершении работы все равно нужно отправить обратно. Но синий парень ничего об этом не знает.
[Если по-настоящему задуматься над этой аналогией, что-то ужасное, технически с зеленоволосым парнем случилось то, что после того, как он переехал, он немедленно покончил с собой. Значит, он не может никого уведомить о том, что задача выполнена ! ]
Чтобы избежать этой проблемы, в случаях , как это только , Swift должен идти непосредственно к дому по этому адресу и фактически изменить волосы текущего обитателя . Это совершенно другой процесс, чем просто отправить нового парня.
Вот почему Swift хочет, чтобы мы использовали mutating
ключевое слово!
Конечный результат выглядит одинаково для всего, что должно относиться к структуре: теперь у обитателя дома голубые волосы. Но на самом деле процессы для его достижения совершенно разные. Похоже, он делает то же самое, но делает совсем другое. Это то, чего вообще не делают Swift-структуры.
Итак, чтобы немного помочь плохому компилятору и не заставлять его выяснять, мутирует ли функция сама по себе struct
или нет для каждой отдельной структурной функции, нас просят сжалиться и использовать mutating
ключевое слово.
По сути, чтобы помочь Swift оставаться быстрым, мы все должны внести свой вклад. :)
РЕДАКТИРОВАТЬ:
Привет, чувак / чувак, который отверг меня, я просто полностью переписал свой ответ. Если вам так больше нравится, вы уберете отрицательный голос?