类内变异函数

Bog*_*Pop 7 class function swift

在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
    }
}
Run Code Online (Sandbox Code Playgroud)

Zombie继承了Monster类的名字字段.

var name = "Monster"
Run Code Online (Sandbox Code Playgroud)

为什么

fredTheZombie.changeName("Tom", walksWithLimp: true) 
Run Code Online (Sandbox Code Playgroud)

即使函数头之前没有变异关键字也可以工作?

dfr*_*fri 16

来自语言指南 - 方法:

从实例方法中修改值类型

结构和枚举是类型.默认情况下,无法在其实例方法中修改值类型的属性.

但是,如果需要在特定方法中修改结构或枚举的属性,则可以选择改变该方法的行为.然后,该方法可以从方法中改变(即更改)其属性,并且当方法结束时,它所做的任何更改都将写回原始结构.该方法还可以为其隐式self 属性分配一个全新的实例,并且该新实例将在方法结束时替换现有实例.

您可以通过将mutating关键字放在该方法的func关键字之前来选择此行为...

因此,我们需要包含关键字mutating以允许类型的成员(例如函数)改变其成员(例如a的成员属性).改变值类型实例的成员意味着改变值类型实例本身(),而改变引用类型实例的成员并不意味着引用类型实例(被认为)的引用被改变.structselfself

因此,由于a class是Swift中的引用类型,我们不需要mutating在类的任何实例方法中包含关键字Zombie,即使它们改变了实例成员或类.如果我们要谈论改变实际的类实例fredTheZombie,我们会提到改变它的实际引用(例如指向另一个Zombie实例).

[†]:作为另一个例子,我们可以使用例如mutatinggetters(get); 在这种情况下,我们需要明确标记这些,因为这些是nonmutating默认情况.set另一方面,Setters()是mutating默认的,因此mutating即使它们改变了值类型的成员也不需要关键字.


小智 6

mutating与类无关,仅与值类型有关,例如structenum