【问题标题】:Swift: always copies on inout?斯威夫特:总是在输入时复制?
【发布时间】:2015-10-07 00:44:23
【问题描述】:

我编写了一个用于序列化模型数据的简单库,后来意识到我只是在阅读时才对数据进行写入。我能够将问题减少到以下操场 sn-p:

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)

结果(对我来说)出乎意料:

写入值:测试

设置名称:测试

我重新阅读了关于inout 参数的部分,但没有看到明确提及复制语义。我的预感是编译器期望该值被覆盖,并且如果没有其他代码这样做的话,它自己会使用初始值进行覆盖。

这似乎是预期的,还是编译器错误?在我看来,这是不直观的行为。我没想到会有分配,除非它来自我的代码——它没有。

为了说明什么是显而易见的,上面的代码 sn-p 不需要 inout 参数,但我一直在使用通用接口进行读写。

【问题讨论】:

  • 非常有趣!顺便说一句,您可以进一步减少它:var x = 0 { didSet { print("Setting") } }; func f(inout x : Int) {}; f(&x)

标签: swift swift2


【解决方案1】:

我代表 Swift 编译器开发人员 Joe Groffon Twitter 发布此内容(请参阅回复)。他很好地回答了我提到这个问题的推文。

他说:

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

【讨论】:

【解决方案2】:

In the document:

通过将 inout 关键字放在其参数定义的开头来编写一个 in-out 参数。一个 in-out 参数有一个值,该值被传入函数,被函数修改,并被传回函数以替换原始值

in-out 参数不是“call-by-reference”,而是“call-by-copy-restore

【讨论】:

    猜你喜欢
    • 2017-07-22
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 2017-11-13
    • 2015-08-19
    • 2014-09-11
    相关资源
    最近更新 更多