Consider this class in 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 inherits the name field from the Monster class.
var name = "Monster"
Why does
fredTheZombie.changeName("Tom", walksWithLimp: true)
work even if there is no mutating keyword before the function header?
Without mutating func
Mutating func
In class, all func are mutating. But for struct and enum we need to specify.
mutating
is not relevant for classes, it is only for value types, such asstruct
andenum
From The Language Guide - Methods:
Hence, we need to include the keyword
mutating
to allow a member (e.g. a function†) of a value type to mutate its members (e.g. the member properties of astruct
). Mutating a member of a value type instance means mutating the value type instance itself (self
), whereas mutating a member of a reference type instance will not mean the reference of the reference type instance (which is consideredself
) is mutated.Hence, since a
class
is a reference type in Swift, we need not include themutating
keyword in any of the instance methods of yourZombie
class, even if they mutate the instance members or the class. If we were to speak of mutating the actual class instancefredTheZombie
, we would refer to mutating its actual reference (e.g. to point at anotherZombie
instance).[†]: As another example, we may use e.g.
mutating
getters (get
); in which case we need to mark this explicitly as these arenonmutating
by default. Setters (set
), on the other hand, aremutating
by default, and hence need nomutating
keyword even if they mutate members of a value type.Another easy to understand example, verified in Swift 3 & 4
Solution