这儿每天共享一个 iOS 的新知识,快来关注我吧

mutating

Swift 中,mutating 关键字用于符号结构体和枚举中的办法,答应这些办法修正实例自身或许实例内部的特点。

在默许情况下,在值类型(结构体和枚举)中的办法中是不答应修正特点的。运用 mutating 关键字能够让办法修正特点,从而到达在值类型中修正自身的意图。

struct Point {
    var x: Double
    var y: Double
    func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

上边这段代码会报错:

mutating 的使用和实现原理

错误提示说的很清楚了,self 是不可变的,假如想让 self 可变,能够在函数名前增加 mutating 关键字。

struct Point {
    ...
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

当咱们为 moveBy 办法运用了 mutating 关键字,将被答应修正 Point 结构体中的特点 xy

其实加了这个关键字之后 self 自身也能够修正:

mutating func moveBy(x deltaX: Double, y deltaY: Double) {
    self = Self(x: x + deltaX, y: y + deltaY)
}

协议中也能够运用

虽然 mutating 关键字是值类型所独有的,但咱们仍然能够将 mutating 函数用在协议上:

protocol GameLife {
    var life: Int { get set }
    mutating func takeDamage(damage: Int)
}

值类型能够直接运用:

struct Player: GameLife {
    var life = 100
    mutating func takeDamage(damage: Int) {
        life -= damage
    }
}

但该协议也或许被用在引证类型,例如类。类在遵守此类协议时需要删去 mutating 关键字,否则编译会报错,因为引证类型本质上是可变的。

class Player: GameLife {
    var life = 100
    func takeDamage(damage: Int) {
        life -= damage
    }
}

mutating 的实现原理

其实增加 mutating 之后,底层默许传入了一个符号了 inoutSelf 参数进来,这样 self 就能够修正了,咱们测验修正一下代码,不运用 mutating 关键字来修正值类型特点:

struct Point {
    var x = 0.0, y = 0.0
    func moveBy(self: inout Self, x deltaX: Double, y deltaY: Double) {
        self.x += deltaX
        self.y += deltaY
    }
}

运用的时候只需要传入 Point 的内存地址

var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(self: &somePoint, x: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// Prints "The point is now at (3.0, 4.0)"

这儿每天共享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 “iOS新知”,每天准时共享一个新知识,这儿仅仅同步,想要及时学到就来关注我吧!