Застереження: терміни неспеціаліста попереду.
Це пояснення не є суворо правильним на найритузнішому рівні коду. Однак це було розглянуто хлопцем, який насправді працює над Свіфтом, і він сказав, що це досить добре як основне пояснення.
Тому я хочу спробувати просто і прямо відповісти на питання "чому".
Якщо бути точним: чому ми повинні позначати функції struct як такі, mutating
коли ми можемо змінювати параметри struct без будь-яких змін ключових слів?
Отже, загальна картина, вона багато в чому пов’язана з філософією, яка підтримує Свіфта стрімким.
Ви можете подумати про це як про проблему управління фактичними фізичними адресами. Коли ви змінюєте свою адресу, якщо багато людей мають вашу поточну, ви повинні повідомити всіх про те, що ви переїхали. Але якщо у вас немає поточної адреси, ви можете просто переїхати куди завгодно, і ніхто не повинен цього знати.
У цій ситуації Свіфт схожий на пошту. Якщо багато людей з великою кількістю контактів багато рухаються, це має дуже високі накладні витрати. Доводиться платити великому штату людей, щоб обробляти всі ці повідомлення, і процес забирає багато часу та зусиль. Ось чому ідеальний штат Свіфта - це те, що кожен у своєму місті має якомога менше контактів. Тоді йому не потрібен великий персонал для обробки змін адреси, і він може робити все інше швидше та якісніше.
Ось чому Swift-люди всі роздумують про типи значень проти стандартних типів. За своєю природою посилальні типи набирають "контактів" повсюдно, і типам цінностей зазвичай не потрібно більше пари. Типи значень - "швидкі" -er.
Отже , повернемося до маленької зображенні: structs
. Структури - це велика справа в Swift, оскільки вони можуть робити більшість речей, які можуть робити об’єкти, але вони є типами цінностей.
Давайте продовжимо аналогію фізичної адреси, уявляючи собі, misterStruct
що живе someObjectVille
. Тут аналогія трохи підмотується, але я думаю, що це все одно корисно.
Тож для моделювання зміни змінної на struct
, скажімо, misterStruct
має зелене волосся і отримує наказ перейти на блакитне волосся. Як я вже говорив, аналогія підморгує, але відбувається щось на зразок того, що замість того, щоб змінити misterStruct
волосся, стара людина виїжджає, а нова людина з синім волоссям заходить, і ця нова людина починає називати себе misterStruct
. Нікому не потрібно отримувати повідомлення про зміну адреси, але якщо хтось подивиться на цю адресу, то побачить хлопця з блакитним волоссям.
Тепер давайте змоделюємо, що відбувається, коли ви викликаєте функцію на struct
. У цьому випадку це як misterStruct
отримати замовлення, наприклад changeYourHairBlue()
. Тож пошта видає вказівку misterStruct
«йди переодягни волосся в блакитне і скажи мені, коли закінчиш».
Якщо він дотримується тієї самої процедури, що і раніше, якщо він робить те, що робив, коли змінну змінювали безпосередньо, то misterStruct
буде рухатися з власного будинку та закликати нову людину з блакитним волоссям. Але в цьому проблема.
Наказ був: «піди переодягни волосся на блакитне і скажи мені, коли закінчиш», але це зелений хлопець отримав це замовлення. Після того, як блакитний хлопець переїжджає, сповіщення про "роботу виконано" все одно потрібно надіслати назад. Але блакитний хлопець про це нічого не знає.
[Щоб насправді підняти цю аналогію чимось жахливим, технічно те, що трапилось із зеленоволосою хлопцею, було те, що після його виїзду він негайно покінчив життя самогубством. Тож він не може нікого повідомити, що завдання теж виконано ! ]
Щоб уникнути цієї проблеми, у випадках , як це тільки , Swift повинен йти безпосередньо до будинку за цією адресою і фактично змінити волосся поточного мешканця . Це зовсім інший процес, ніж просто надсилання нового хлопця.
І тому Свіфт хоче, щоб ми використовували mutating
ключове слово!
Кінцевий результат виглядає однаковим для будь-чого, що має стосуватися структури: мешканець будинку тепер має сині волосся. Але процеси її досягнення насправді абсолютно різні. Схоже, він робить одне і те ж, але робить зовсім інше. Це робить те, чого Swift загалом ніколи не робить.
Тож, щоб надати бідному компілятору невелику допомогу, а не змушувати його з’ясовувати, чи функція мутує struct
чи ні, сама по собі для кожної окремої функції структури, нас просять пожаліти і використовувати mutating
ключове слово.
По суті, щоб допомогти Свіфту залишатися стрімким, ми всі повинні зробити все, що від нас залежить. :)
Редагувати:
Гей, чувак / дудет, хто мене проголосував, я просто повністю переписав свою відповідь. Якщо вам це буде сидіти краще, ви знімете голос проти?