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

相关推荐
AI云海8 小时前
iOS 多 Target 打包、UAT/生产测试与上架 App Store 全流程指南
ios
阿里超级工程师10 小时前
最新快速申请ios打包证书和profile文件步骤
ios·打包证书
2501_9159090614 小时前
iOS 应用反调试技详解术 检测调试器的原理与防护实践
android·ios·小程序·https·uni-app·iphone·webview
游戏开发爱好者815 小时前
TraceEagle 代理抓包详解,无感代理、去证书绑定与 HTTP/3 解密能力解析
网络协议·计算机网络·网络安全·ios·adb·https·udp
aiopencode16 小时前
SwiftUI Introspect生产环境完全指南:为什么它是安全可靠的选择
后端·ios
for_ever_love__17 小时前
iOS: 网络管理单例
学习·ios·objective-c
00后程序员张17 小时前
iOS加固技术路线全面解析:Bitcode模式、源码模式与汇编模式对比及爱加密优势
android·汇编·ios·小程序·uni-app·cocoa·iphone
ii_best1 天前
更新!移动端开发软件按键安卓版&手机助手v5.1.0上线!本地AI识别全面解锁,脚本开发再升级
android·人工智能·ios·按键精灵
weixin_403810131 天前
03-iOS免越狱无线投屏-上传图片和视频到相册
ios·新媒体运营·跨境电商·ios自动化·ios投屏·ios智能体·ios脚本
2501_916007471 天前
SwiftUI 声明式语法与 Xcode 预览功能详解
ide·vscode·ios·swiftui·个人开发·xcode·敏捷流程