Swift 2.0'inout'函数参数和计算属性

mes*_*ngr 7 swift swift2

我正在测试Swift 2.0 beta,并发现了奇怪的行为.这是一个示例代码:

private func someFunc(inout someString: String) {
    print("Inside \'someFunc()\'")

    print(someString)
    someString = "Some another string"
}

private var someAncillaryInt = 42

print(someAncillaryInt)

private var someString: String {
    get {
        print("Inside \'getter\'")

        return "Some string"
    }
    set {
        print("Inside \'setter\'")
        someAncillaryInt = 24
    }
}

someFunc(&someString)
print(someAncillaryInt)
Run Code Online (Sandbox Code Playgroud)

输出:

42

在'getter'里面

在'someFunc()'里面

一些字符串

内部'二传手'

24

我不明白为什么不吸气,同时打印称为someString内部someFunc()以及为什么它时,someFunc()得到了与传递someString.

可以假设我还没有理解inout参数的复杂性,并且在传递之后因为inout参数计算属性停止,em,"计算",但为什么在我们设置另一个值时调用'setter' someString

谢谢!

UPD:我在下面添加了答案.

更新2015年11月18日:Apple已经更新了他们的手册,详细解释了如何使用params.

Mar*_*n R 6

您可能会因为选择someString全局变量的名称和someFunc()函数的参数名称 而导致混淆.

print(someString)inside someFunc()打印(local)函数参数的值,该参数与全局someString变量完全无关(并隐藏).

如果重命名函数参数,则更容易理解

private func someFunc(inout localString: String) {
    print("Inside \'someFunc()\'")
    print(localString)
    localString = "Some another string"
}
Run Code Online (Sandbox Code Playgroud)

它在语义上是相同的(因此产生相同的输出).

你可以想到

someFunc(&someString)
Run Code Online (Sandbox Code Playgroud)

如下:

  • someString检索值(使用getter方法).
  • someFunc()执行,本地参数localString 设置为值someString.
  • 返回时someFunc(),someString将(使用setter方法)设置为local参数的(可能已更改)值 localString.

有关详细信息,访问Apple Developer Forum的https://devforums.apple.com/thread/230567,例如:

鉴于getter和setter的保证,inout自然地遵循:当使用inout参数调用函数时,逻辑上它调用var/subscript上的getter并将值复制到临时堆栈中,这保证具有物理可寻址性.临时的物理地址被传递给函数的inout参数.... 被调用者使用该内存位置执行任何所需的操作(并且永远不知道传入的内容是否已计算).当被调用者返回时,调用setter将值复制回原位.

它还保证传入inout的属性的getter/setter将调用一次getter和setter,无论被调用者做什么(如果访问者有副作用或价格昂贵,这很重要).

但也有人说,如有必要,可以避免临时复制.