类内变异函数

时间:2016-07-17 15:20:41

标签: swift function class

在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继承了Monster类的名字字段。

var name = "Monster"

为什么

fredTheZombie.changeName("Tom", walksWithLimp: true) 
即使函数头之前没有变异关键字,

也可以工作吗?

4 个答案:

答案 0 :(得分:15)

来自The Language Guide - Methods

  

从实例方法中修改值类型

     

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

     

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

     

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

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

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

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

答案 1 :(得分:6)

mutating与类无关,只适用于值类型,例如structenum

答案 2 :(得分:2)

不改变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()

变异功能

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()

在课堂上,所有的功能都在变异。但是对于struct和enum,我们需要指定。

答案 3 :(得分:2)

另一个易于理解的例子,在 Swift 3& 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"

<强> 解决方案

mutating func changePopulation(newpopulation : Int)