Uwaga: terminy laika przed nami.
To wyjaśnienie nie jest rygorystycznie poprawne na najbardziej skomplikowanym poziomie kodu. Jednak zostało sprawdzone przez gościa, który faktycznie pracuje nad Swiftem i powiedział, że jest wystarczająco dobre jako podstawowe wyjaśnienie.
Więc chcę spróbować prosto i bezpośrednio odpowiedzieć na pytanie „dlaczego”.
A dokładniej: dlaczego musimy oznaczać funkcje struktury jako takie, w mutating
których możemy zmieniać parametry struktury bez modyfikowania słów kluczowych?
Tak więc, ogólnie rzecz biorąc, ma to wiele wspólnego z filozofią, która sprawia, że Swift jest szybki.
Można o tym pomyśleć jak o problemie zarządzania rzeczywistymi adresami fizycznymi. Gdy zmieniasz adres, jeśli jest dużo osób, które mają Twój obecny, musisz powiadomić je wszystkie o przeprowadzce. Ale jeśli nikt nie ma Twojego aktualnego adresu, możesz po prostu przenieść się w dowolne miejsce i nikt nie musi o tym wiedzieć.
W tej sytuacji Swift przypomina trochę pocztę. Jeśli wiele osób z wieloma kontaktami dużo się przemieszcza, wiąże się to z naprawdę dużymi kosztami. Za obsługę tych wszystkich powiadomień musi płacić wielu ludzi, a proces ten zajmuje dużo czasu i wysiłku. Dlatego idealnym stanem Swifta jest, aby każdy w jego mieście miał jak najmniej kontaktów. Wtedy nie potrzebuje dużego personelu do obsługi zmian adresów, a wszystko inne może zrobić szybciej i lepiej.
To jest również powód, dla którego wszyscy Swift-ludzie zachwycają się typami wartości w porównaniu do typów referencyjnych. Z natury typy referencyjne gromadzą „kontakty” w każdym miejscu, a typy wartości zwykle nie potrzebują więcej niż kilka. Typy wartości to „Swift” -er.
Wracając do małego obrazu: structs
. Struktury to wielka sprawa w Swift, ponieważ mogą robić większość rzeczy, które mogą robić obiekty, ale są typami wartości.
Kontynuujmy analogię adresu fizycznego, wyobrażając sobie, misterStruct
że żyje w someObjectVille
. Tutaj analogia jest nieco skomplikowana, ale myślę, że nadal jest pomocna.
Tak więc, aby modelować zmianę zmiennej na struct
, powiedzmy, że misterStruct
ma zielone włosy i dostaje polecenie przejścia na niebieskie włosy. Jak powiedziałem, analogia staje się niewyjaśniona, ale w pewnym sensie dzieje się tak, że zamiast zmieniać misterStruct
włosy, stara osoba wyprowadza się i pojawia się nowa osoba z niebieskimi włosami i ta nowa osoba zaczyna nazywać siebie misterStruct
. Nikt nie musi otrzymywać powiadomienia o zmianie adresu, ale jeśli ktoś spojrzy na ten adres, zobaczy faceta z niebieskimi włosami.
Teraz zamodelujmy, co się dzieje, gdy wywołujesz funkcję na struct
. W tym przypadku to tak, jakby misterStruct
otrzymać takie zamówienie jak changeYourHairBlue()
. Tak więc poczta dostarcza polecenie misterStruct
„idź zmienić włosy na niebieskie i powiedz mi, kiedy skończysz”.
Jeśli on zgodnie z tą samą procedurę jak wcześniej, jeśli robi to, co zrobił, gdy zmienna została zmieniona bezpośrednio, co misterStruct
zrobi to wyjść z własnego domu i rozmowy w nowej osoby z niebieskimi włosami. Ale to jest problem.
Rozkaz brzmiał: „Zmień włosy na niebieskie i powiedz mi, kiedy skończysz”, ale to zielony facet dostał to zamówienie. Po wprowadzeniu się niebieskiego faceta nadal trzeba odesłać powiadomienie o ukończeniu zadania. Ale ten niebieski nic o tym nie wie.
[Aby naprawdę wywnioskować tę analogię, coś okropnego, technicznie rzecz biorąc, zielonowłosemu facetowi przydarzyło się to, że po wyprowadzce natychmiast popełnił samobójstwo. Więc nie może też nikogo powiadomić, że zadanie zostało wykonane ! ]
Aby uniknąć tego problemu, w takich przypadkach tylko , Swift musi przejść bezpośrednio do domu pod tym adresem i rzeczywiście zmienić bieżący mieszkańców regionu, włosy . To zupełnie inny proces niż zwykłe wysłanie nowego faceta.
I dlatego Swift chce, abyśmy używali mutating
słowa kluczowego!
Efekt końcowy wygląda tak samo w przypadku wszystkiego, co musi odnosić się do struktury: mieszkaniec domu ma teraz niebieskie włosy. Ale procesy służące do osiągnięcia tego są w rzeczywistości zupełnie inne. Wygląda na to, że robi to samo, ale robi zupełnie inną rzecz. Robi coś, czego generalnie struktury Swift nigdy nie robią.
Tak więc, aby dać biednemu kompilatorowi trochę pomocy i nie zmuszać go do zastanawiania się, czy funkcja sama mutuje, struct
czy nie, dla każdej pojedynczej funkcji struktury kiedykolwiek, jesteśmy proszeni o litość i użycie mutating
słowa kluczowego.
Zasadniczo, aby pomóc Szybkiemu zachować szybkość, wszyscy musimy wykonać swoją część. :)
EDYTOWAĆ:
Hej koleś / koleś, który mnie zlekceważył, właśnie całkowicie przepisałem swoją odpowiedź. Jeśli z tobą będzie lepiej, czy usuniesz głos przeciw?