使用inout关键字:是通过引用传递或通过复制复制(/按值结果调用)传递的参数 [英] Using inout keyword: is the parameter passed-by-reference or by copy-in copy-out (/call by value result)

查看:175
本文介绍了使用inout关键字:是通过引用传递或通过复制复制(/按值结果调用)传递的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:基于以下信息和讨论:inout参数是引用传递还是是以复制方式复制出的?

Question: Based on the information and discussion below: Are inout parameters passed-by-reference or by copy-in copy-out?

基于以下SO线程,由关键字标记的函数参数被引用传递:

Based on the following SO threads, function parameters marked by the inout keyword is passed by reference:

  • Does inout/var parameter make any difference with reference type?
  • Is Swift Pass By Value or Pass By Reference
  • Why doesn't inout pass by reference?

我们注意到,最上面的两个线程是Swift 2.0之前的版本;我无法在SO上找到关于此主题的任何新讨论(除了有些相关的第三线程链接).

We note that the two top-most threads are pre-Swift 2.0; I haven't been able to find any newer discussion on the subject here on SO (except the somewhat related third thread link).

根据Apple的文档(据我所知),由inout关键字标记的函数参数由 copy-in copy-out (或按值调用结果)

Based on Apple's documentation (as far as I've been able to discern), however, function parameters marked by the inout keyword is passed by copy-in copy-out (or call by value result)

进出参数按如下方式传递:

In-out parameters are passed as follows:

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

When the function is called, the value of the argument is copied. In the body of the function, the copy is modified. When the function returns, the copy’s value is assigned to the original argument. This behavior is known as copy-in copy-out or call by value result. ...

  • Apple语言指南:功能-内-外参数:
    • Apple Language Guide: Functions - In-Out Parameters:
    • ...您可以通过将inout关键字放在 其参数定义的开始.输入输出参数具有值 被传递给该功能,被该功能修改, 并传递回该功能以替换原始功能 值. ...

      ... You write an in-out parameter by placing the inout keyword at the start of its parameter definition. An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value. ...


      现在以我自己的示例尝试对此进行调查:


      Now for my own example trying to investigate this:

      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参数前面加上一个&符号(&),所以这样做确实合乎逻辑".

      This example would imply that inout parameters are indeed passed by reference (as is noted in the two linked SO threads above). Since we prefix the inout parameter with an ampersand (&) this does "feel" logical.

      要尽最大努力确保我的示例具有代表性--因为这里inout参数myLocalStruct作为类属性发送---我还确保了myLocalStruct没有得到一些幕后花絮" 引用,因为它是类属性:

      To try my best to make sure that my example is representative---since here inout parameter myLocalStruct is sent as class property---I also made sure that the myLocalStruct didn't get some "behind-the-hood" reference due to it being a class property:

      // ... 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确实是函数局部的,因此按值传递(无须背后引用).

      Ok, myLocalStruct in this example really function-local, and hence passed by value (no reference-behind-the-hood).

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

      Result: Given the above, inout parameters are passed by reference?

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

      I have two possible follow-up questions:

      1. 我是否误解了Apple语言文档中关于inout的描述,它可以解释为通过引用传递"吗?
      2. 或者,我的例子仍然不能代表这种情况吗?
      1. Have I misinterpreted the description on inout in the Apple language doc, can it be interpreted as "pass by reference"?
      2. Or, is my example still not representative for this case?

      推荐答案

      《语言参考》中的以下两段对此进行了更详细的描述:

      The next two paragraphs in the Language Reference describes it more in detail:

      进出参数

      ...

      In-Out Parameters

      此行为称为复制入复制"或按值调用"结果.为了 例如,当计算属性或具有观察者的属性为 作为in-out参数传递时,其getter被称为 函数调用及其设置器被称为函数返回的一部分.

      This behavior is known as copy-in copy-out or call by value result. For example, when a computed property or a property with observers is passed as an in-out parameter, its getter is called as part of the function call and its setter is called as part of the function return.

      作为优化,当参数是存储在物理变量上的值时 内存中的地址,内部和内部都使用相同的存储位置 在功能主体之外. 优化的行为称为呼叫方" 参考;满足复制的所有要求 复制模型,同时消除了复制的开销. 不要依赖 签入和签出之间的行为差​​异 参考.

      As an optimization, when the argument is a value stored at a physical address in memory, the same memory location is used both inside and outside the function body. The optimized behavior is known as call by reference; it satisfies all of the requirements of the copy-in copy-out model while removing the overhead of copying. Do not depend on the behavioral differences between copy-in copy-out and call by reference.

      因此实际上是通过引用传递"

      So it's de facto "pass by reference"

      这篇关于使用inout关键字:是通过引用传递或通过复制复制(/按值结果调用)传递的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆