如果你在协议中标记实例方法需求为 mutating ,在为类实现该方法的时候不需要写 mutating 关键字。 mutating 关键字只在结构体和枚举类型中需要书写。
结构体和枚举是值类型。默认情况下,值类型的属性不能在它的实例方法中被修改。
如果你确实需要在某个特定的方法中修改结构体或者枚举的属性,你可以为这个方法选择可变(mutating)行为,然后就可以从其方法内部改变它的属性;并且这个方法做的任何改变都会在方法执行结束时写回到原始结构中。方法还可以给它隐含的self属性赋予一个全新的实例,这个新实例在方法结束时会替换现存实例。
要使用可变方法,将关键字mutating 放到方法的func关键字之前就可以了:
struct Point {
var x = 0.0, y = 0.0
mutating func moveByX(deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(deltaX: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// 打印 "The point is now at (3.0, 4.0)"
上面的Point结构体定义了一个可变方法 moveByX(_:y:) 来移动Point实例到给定的位置。该方法被调用时修改了这个点,而不是返回一个新的点
方法定义时加上了mutating关键字,从而允许修改属性。
在可变方法中给 self 赋值
可变方法能够赋给隐含属性self一个全新的实例。上面Point的例子可以用下面的方式改写:
struct Point {
var x = 0.0, y = 0.0
mutating func moveByX(deltaX: Double, y deltaY: Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(deltaX: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// 打印 "The point is now at (3.0, 4.0)"
新版的可变方法moveBy(x:y:)创建了一个新的结构体实例,它的 x 和 y 的值都被设定为目标值。调用这个版本的方法和调用上个版本的最终结果是一样的。