斯威夫特:总是在里面复制?

时间:2015-10-06 16:24:18

标签: swift swift2

我编写了一个用于序列化模型数据的简单库,后来意识到当我只是阅读时我正在写入数据。我能够将问题减少到以下游乐场片段:

class Foo {
    init() { name = "test" }
    var name:String { didSet { print("setting name: \(self.name)") }}
}


func map(inout foo:String) {
    print("writing value: \(foo)")
}

var foo:Foo = Foo()
map(&foo.name)

结果是(对我而言)意外:

  

写作值:测试

     

设置名称:test

我已经重新阅读了inout参数的部分,但没有明确提到复制语义。我的预感是编译器期望覆盖该值,并且如果没有其他代码这样做,则使用初始值。

这似乎是预期的,还是编译器错误?以我的拙见,这是不直观的行为。我不期待任务,除非它源于我的代码 - 它没有。

要陈述希望显而易见的内容,上面的代码片段不需要inout参数,但我一直在使用通用接口进行读写。

2 个答案:

答案 0 :(得分:3)

我是代表Joe Groff发布的,这是一个Swift编译器开发人员on Twitter(参见回复)。他很好地回答了我提到这个问题的推文。

他说:

  

Inout具有值结果语义。 didSet在inout的末尾接收修改后的值。如果差异是不可观察的(模数无效别名),它只会优化传递引用。 Swift书也应该用这个信息更新。

答案 1 :(得分:2)

In the document

  

您可以通过将inout关键字放在其参数定义的开头来编写输入输出参数。输入输出参数具有传递给函数的值,由函数修改,并从函数传递回替换原始值

输入输出参数不是“按引用调用”,而是“call-by-copy-restore