/ / Funkcja mutacji w klasie - szybka, funkcja, klasa

Funkcja mutingu w klasie - szybka, funkcja, klasa

Rozważ tę klasę w Swift:

class Zombie: Monster {
var walksWithLimp = true

final override func terrorizeTown()
{
town?.changePopulation(-10)
super.terrorizeTown()
}

func changeName(name: String, walksWithLimp: Bool)
{
self.name = name
self.walksWithLimp = walksWithLimp
}
}

Zombie dziedziczy pole nazwy od klasy Monster.

var name = "Monster"

Dlaczego

fredTheZombie.changeName("Tom", walksWithLimp: true)

działa, nawet jeśli przed nagłówkiem funkcji nie ma słowa kluczowego mutującego?

Odpowiedzi:

12 dla odpowiedzi № 1

Od Przewodnik językowy - metody:

Modyfikowanie typów wartości z metod wewnątrz instancji

Struktury i wyliczenia są wartość typy. Domyślnie właściwości typu wartości nie można modyfikować z poziomu jego instancji metody

Jeśli jednak musisz zmodyfikować właściwościtwoja struktura lub wyliczenie w ramach określonej metody, możesz włączyć mutowanie zachowanie dla tej metody. Metoda może następnie mutować (to znaczy zmieniać) jego właściwości w obrębie metody i wszelkie zmiany, które wprowadza są zapisywane z powrotem do oryginalnej struktury po zakończeniu metody. The Metoda może również przypisać całkowicie nową instancję do jej niejawnej self , a ta nowa instancja zastąpi istniejącą, gdy metoda się kończy.

Możesz wyrazić zgodę na to zachowanie, umieszczając mutating słowo kluczowe wcześniej słowo kluczowe func dla tej metody ...

Dlatego musimy dołączyć słowo kluczowe mutating aby zezwolić członkowi (np. funkcji) wartość wpisz, aby zmutować jego członków (np. właściwości członka struct). Mutowanie elementu instancji typu wartości oznacza mutowanie samej instancji typu wartości (self), podczas gdy mutowanie członka odniesienie instancja typu nie będzie oznaczać odwołania do instancji typu odwołania (która jest brana pod uwagę self) jest zmutowany.

Stąd, ponieważ a class jest typem referencyjnym w Swift, nie musimy uwzględniać mutating słowo kluczowe w dowolnej z Twoich metod instancji Zombie klasa, nawet jeśli mutują członków instancji lub klasę. Gdybyśmy mieli mówić o mutowaniu rzeczywistej instancji klasy fredTheZombie, odnosilibyśmy się do mutacji jego faktycznej odniesienie (np. aby wskazać inną Zombie instancja).

[†]: Jako kolejny przykład możemy użyć np. mutating getters (get); w takim przypadku musimy to wyraźnie zaznaczyć nonmutating domyślnie. Setery (set), z drugiej strony są mutating domyślnie i dlatego nie trzeba mutating słowo kluczowe, nawet jeśli mutują członków typu wartości.


4 dla odpowiedzi nr 2

mutating nie dotyczy klas, dotyczy tylko typów wartości, takich jak struct i enum


1 dla odpowiedzi nr 3

Bez mutowania func

struct Counter {
let count: Int

init(count: Int = 0) {
self.count = count
}

// the functional approach
func counterByIncrementing() -> Counter {
let newCount = count + 1
return Counter(count: newCount)
}
}

var counter = Counter()
counter = counter.counterByIncrementing()

Mutowanie func

struct Counter {
// this now has to be a var :/
var count: Int

init(count: Int = 0) {
self.count = count
}

// the mutating keyword approach
mutating func increment() {
count += 1
}
}

var counter = Counter()
counter.increment()

W klasie wszystkie func mutują się. Ale dla struct i enum musimy sprecyzować.


1 dla odpowiedzi nr 4

Kolejny łatwy do zrozumienia przykład, zweryfikowany w Swift 3 i 4

struct City
{
var population : Int

func changePopulation(newpopulation : Int) {
population = newpopulation //error: cannot modify property "population"
}
}

var mycity = City(population : 500)
mycity.changePopulation(newpopulation : 2000) //error: cannot modify property "population"

Rozwiązanie

mutating func changePopulation(newpopulation : Int)