将值类型变量传递给函数时如何复制它,该副本是什么?

时间:2016-08-17 14:59:45

标签: swift function value-type

  

Swift的字符串类型是值类型。如果创建新的String值,则在将String值传递给函数或方法时,或者将其赋值给常量或变量时,将复制该String值。

分配给常量或变量时会复制它,这对我来说很有意义。但是当传递给函数的值类型变量也会被复制时,这会让我感到困惑。

问题

将值类型变量传递给函数时如何复制?什么样的空间"持有这份副本?它是在场景后面无形地创建的某种临时变量,在函数进程被破坏之后?

谢谢

2 个答案:

答案 0 :(得分:3)

Swift中的值类型被复制,但在大多数情况下,只有一些小细节被复制,大多数数据保持不变。以String值为例。将值传递给函数时,会复制一些信息,比如指向字符缓冲区的实际指针或其长度,但实际数据才会被传递。这意味着在Swift中传递值是一种快速操作。

当Swift检测到需要在其上写入时,它会克隆实际数据。例如,如果数组从let传递到var,则不会生成主要副本。但是,如果通过附加新元素来更新新数组,那么此时将创建数组内容的克隆,并在那里添加新元素。

答案 1 :(得分:3)

将值类型传递给函数时,请将其视为将其分配给范围为该函数的局部变量,因此复制行为类似于仅分配新的局部变量。

关于复制的位置,我们应该认识到复制行为实际上比听起来更复杂。正如他们在Building Better Apps with Value Types in Swift (WWDC 2015, Session 414)中所指出的那样,"副本很便宜":

  

复制低级基本类型是恒定时间

     
      
  • IntDouble
  •   
     

复制值类型的struct,enum或tuple是常量时间

     
      
  • CGPoint
  •   
     

可扩展数据结构使用copy-on-write

     
      
  • 复制涉及固定数量的引用计数操作

  •   
  • StringArraySetDictionary

  •   

关于最后一点,在幕后,Swift做了一些简单的手工,避免了每次引用时复制可扩展的值类型,而只是指向原始引用,但跟踪有多少引用和实际上只在写作时复制(a);其中(b)有多个参考文献。 that video中会更详细地讨论此行为。