根据《 Swift编程语言指南》(针对Swift 4.2)中的“内存安全性”一章,有一句话“一个函数可以对其所有in-out参数进行长期写访问”。 https://docs.swift.org/swift-book/LanguageGuide/MemorySafety.html
我创建了一个新的命令行工具项目,以在Xcode 10.1中对其进行验证。
var stepSize = 1
func increment(_ number: inout Int) {
print(stepSize)
}
increment(&stepSize)
我希望输出为1,但实际输出为崩溃日志“同时访问0x100587430,但修改需要互斥访问”。
我知道这是关于访问输入输出参数的冲突,但是我不知道为什么会发生这种情况。为什么函数对所有输入输出参数都具有长期写访问权限?
答案 0 :(得分:2)
此API的使用者看到func increment(_ number: inout Int)
,但看不到实现。原则上只能假设increment(_:)
对参数进行写操作,因为它可以。
即使函数实现当前不执行任何写操作,也存在这种可能性,因此编译器必须假设最坏的情况。想象一下,如果允许某些客户端代码对此进行编译,则将其视为只读(因为当时是这种情况)。当有人将number += 1
添加到函数主体时,客户端代码应该怎么处理?
这类似于拥有一个可以声明为throw
的函数,而其实际实现不是throw
。编译器仍然将其视为throw,并需要使用try
的某些变体来处理错误。