bri*_*efy 2 memory-safety swift
参考官方教程,swift中存在内存冲突,但是,根据我的javascript知识,不存在内存冲突,下面的代码总是正确的。
func balance(_ x: inout Int, _ y: inout Int) {
let sum = x + y
x = sum / 2
y = sum - x
}
var playerOneScore = 42
var playerTwoScore = 30
balance(&playerOneScore, &playerTwoScore) // OK
balance(&playerOneScore, &playerOneScore) // Error: conflicting accesses to playerOneScore
Run Code Online (Sandbox Code Playgroud)
来自内存安全:
\n\n\n具体来说,如果您有两个满足\n以下所有条件的访问,则会发生冲突:
\n\n
\n- 至少一个是写访问或非原子访问。
\n- 他们访问内存中的同一位置。
\n- 它们的持续时间重叠。
\n
然后:
\n\n\n函数对其所有输入输出参数具有长期写入访问权限。\n输入输出参数的写入访问在所有\n非输入输出参数求值后开始,并持续\n整个持续时间该函数调用。
\n
因此,将相同的变量作为输入输出参数传递给
\nfunc balance(_ x: inout Int, _ y: inout Int) \nRun Code Online (Sandbox Code Playgroud)\n算作对同一内存位置的重叠写访问,因此算作冲突。
\n有关基本原理和更多详细信息,请参阅SE-0176 Enforce Exclusive Access to Memory,它已在 Swift 4 中实现。特别是,强制执行独占内存访问
\n举个例子,如果将相同的变量作为 inout 参数传递,则以下两个看似等效的函数实际上并不等效,因此变异x会产生影响y,反之亦然:
func balance(_ x: inout Int, _ y: inout Int) {\n let sum = x + y\n x = sum / 2\n y = sum - x\n}\n\nfunc balance(_ x: inout Int, _ y: inout Int) {\n x = (x + y) / 2\n y = (x + y) / 2 - x\n}\nRun Code Online (Sandbox Code Playgroud)\n另一个例子:
\nvar global = 0\nfunc foo(_ x: inout Int, _ y: inout Int) {\n x += y\n global = y\n}\nRun Code Online (Sandbox Code Playgroud)\n如果变异x可能会修改y,反之亦然,则编译器无法优化代码以y首先将 的值加载到寄存器中,即执行相当于
func foo(_ x: inout Int, _ y: inout Int) {\n let savedY = y\n x += savedY\n global = savedY\n}\nRun Code Online (Sandbox Code Playgroud)\n还讨论了(请参阅消除非瞬时访问?)通过在函数调用期间制作临时副本来消除长期访问,这些副本在函数返回时分配回来,即执行类似的操作
\nfunc balance(_ x: inout Int, _ y: inout Int) {\n var (localX, localY) = (x, y)\n let sum = localX + localY\n localX = sum / 2\n localY = sum - localX\n (x, y) = (localX, localY)\n}\nRun Code Online (Sandbox Code Playgroud)\n这个想法被放弃了,因为它对性能不利,即使对于 \xe2\x80\x9csimple types\xe2\x80\x9d 来说也是如此,但对于 \xe2\x80\x9ccontainer types\xe2\x80\x9d like 来说更糟糕Array。
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |