使用inout关键字:是通过引用传递的参数或通过copy-in copy-out(/按值结果调用)

时间:2015-12-21 16:49:26

标签: swift2 inout

问题:根据以下信息和讨论:inout参数通过引用传递通过copy-in copy-out

根据以下SO线程,inout关键字标记的函数参数通过引用传递

我们注意到两个最顶层的线程都是Swift 2.0之前的版本;我在SO上找不到关于这个主题的任何新讨论(除了有点相关的第三线程链接)。

根据Apple的文档(据我能够辨别),inout关键字标记的功能参数由 copy-in copy-out 传递(或按值结果调用

  

输入输出参数传递如下:

     

调用该函数时,复制参数的值。在   功能正文,副本被修改。当功能   返回,将副本的值分配给原始参数。这个   行为称为 copy-in copy-out 或按值调用结果。 ...

  

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

现在我试图对此进行调查:

struct MyStruct {
    private var myInt: Int

    mutating func increaseMyInt() {
        myInt++
    }

    func printMyInt() {
        print(String(myInt))
    }

    init(int: Int) {
        myInt = int
    }
}

class MyClass {
    var myStruct: MyStruct

    init(int: Int) {
        myStruct = MyStruct(int: 1)
    }

    func printMyStructsInt() {
        print(String(myStruct.printMyInt()))
    }
}

func myInOutFunc(inout myLocalStruct: MyStruct, myClass: MyClass) -> Int {
    myClass.printMyStructsInt() // prints "1", OK
    myLocalStruct.increaseMyInt()
    myClass.printMyStructsInt() // prints "2": so myStruct is not a copy here?
    myLocalStruct.increaseMyInt()

    return 0
        // according to Apple's doc, shouldn't myStruct member of myClass get
        // assigned (copy of) value of myLocalStruct at this point, and not
        // prior to this?
}

var a = MyClass(int: 1)

a.printMyStructsInt() // prints "1", OK
myInOutFunc(&a.myStruct, myClass: a)
a.printMyStructsInt() // prints "3", OK

此示例意味着inout参数确实通过引用传递(如上面两个链接的SO线程中所述)。由于我们在inout参数前加上一个&符号(&),因此“感觉”合乎逻辑。

尽我所能确保我的示例具有代表性 - 因为此处inout参数myLocalStruct作为类属性发送---我也确保myLocalStruct没有得到一些“幕后”引用,因为它是一个类属性:

// ... add to bottom of the code above

func testSendStructAsPublicClassProperty(var myLocalStruct: MyStruct) {
    myLocalStruct.increaseMyInt()
}

// test that sending class property doesn't "reference" things up
a.printMyStructsInt() // prints "3"
testSendStructAsPublicClassProperty(a.myStruct)
a.printMyStructsInt() // prints "3", OK (only copy of class property is sent)

好的,这个例子中的myLocalStruct确实是函数本地的,因此通过值传递(没有引用引擎)。

结果:鉴于上述情况,inout参数是通过引用传递的?

我有两个可能的后续问题:

  1. 我是否误解了Apple语言文档中inout的描述,是否可以将其解释为“通过引用传递”?
  2. 或者,我的例子在这个案例中仍然不具代表性吗?

1 个答案:

答案 0 :(得分:2)

“语言参考”中的下两段更详细地描述了它:

  

输入输出参数

     

...

     

此行为称为copy-in copy-out或按值调用结果。对于   例如,当计算属性或具有观察者的属性是   作为in-out参数传递,其getter作为一部分被调用   函数调用及其setter作为函数return的一部分被调用。

     

作为优化,当参数是存储在物理上的值时   在内存中的地址,内部和内部都使用相同的内存位置   功能体外。 优化的行为称为call by   参考;它满足了复制的所有要求   复制模型,同时消除了复制的开销。 不依赖   关于拷入式拷贝和呼叫的行为差异   参考

所以它实际上是“通过参考传递”