mutating 的使用和实现原理

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

mutating

在 Swift 中,mutating 关键字用于标记结构体和枚举中的方法,允许这些方法修改实例自身或者实例内部的属性。

在默认情况下,在值类型(结构体和枚举)中的方法中是不允许修改属性的。使用 mutating 关键字可以让方法修改属性,从而达到在值类型中修改自身的目的。

swift 复制代码
struct Point {
    var x: Double
    var y: Double
    
    func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

上边这段代码会报错:

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

swift 复制代码
struct Point {
    ...
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

当我们为 moveBy 方法使用了 mutating 关键字,将被允许修改 Point 结构体中的属性 xy

其实加了这个关键字之后 self 本身也可以修改:

swift 复制代码
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
    self = Self(x: x + deltaX, y: y + deltaY)
}

协议中也可以使用

尽管 mutating 关键字是值类型所独有的,但我们仍然可以将 mutating 函数用在协议上:

swift 复制代码
protocol GameLife {
    var life: Int { get set }
    mutating func takeDamage(damage: Int)
}

值类型可以直接使用:

swift 复制代码
struct Player: GameLife {
    var life = 100
    mutating func takeDamage(damage: Int) {
        life -= damage
    }
}

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

kotlin 复制代码
class Player: GameLife {
    var life = 100
    func takeDamage(damage: Int) {
        life -= damage
    }
}

mutating 的实现原理

其实添加 mutating 之后,底层默认传入了一个标记了 inoutSelf 参数进来,这样 self 就可以修改了,我们尝试修改一下代码,不使用 mutating 关键字来修改值类型属性:

swift 复制代码
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 的内存地址:

swift 复制代码
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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
karshey41 分钟前
【IOS webview】IOS13不支持svelte 样式嵌套
ios
潜龙95271 小时前
第4.3节 iOS App生成追溯关系
macos·ios·cocoa
游戏开发爱好者810 小时前
iOS App 电池消耗管理与优化 提升用户体验的完整指南
android·ios·小程序·https·uni-app·iphone·webview
程序员老刘15 小时前
AI智能体正在颠覆App开发,不转型就淘汰
flutter·客户端·mcp
神策技术社区16 小时前
iOS 全埋点点击事件采集白皮书
大数据·ios·app
wuyoula17 小时前
iOS V2签名网站系统源码/IPA在线签名/全开源版本/亲测
ios
2501_9159184118 小时前
iOS 性能监控工具全解析 选择合适的调试方案提升 App 性能
android·ios·小程序·https·uni-app·iphone·webview
fishycx18 小时前
iOS 构建配置与 AdHoc 打包说明
ios
冉冉同学18 小时前
【HarmonyOS NEXT】解决Repeat复用导致Image加载图片展示的是上一张图片的问题
android·前端·客户端
90后的晨仔19 小时前
ios 集成阿里云的AI智能体报错CocoaPods could not find compatible versions for pod "AUIAICal
ios