Swift 如何实现 Array 的写时复制行为?

How Swift implement Array's copy-on-write behavior?

看完build better apps with value type。在他们制作的 photoshop 示例中,他们说

the only thing that gets copied in the two instances of that diagram are the tiles that contain the person's shirt. So even though I have two distinct documents, the old state and the new state, the only new data that I have had to consume as a result of that is the tiles contained in this person's shirt.

所以我开始想知道这两个数组在内存中会是什么样子。所以我做了个小实验。

struct Test {
    var i: Int
    var j: Int
}

var valueArray = [Test(i: 1, j: 9), Test(i: 2, j: 7)]
var valueArray2 = valueArray

当我打印 valueArray 和 valueArray2 的地址时,它们不一样。
"Maybe they implement this by store pointer in array?"
但是当我使用 lldb 打印内存内容时,它们实际上只是 4 Int (1,9,2,7).
所以我很困惑,我什至还没有更改数组。他们似乎复制了整个数组?那我哪里理解错了?
我用来打印结构地址的函数是使用@nschum在this question.

中提供的方法
func address(o: UnsafePointer<Void>) {
    let addr = unsafeBitCast(o, Int.self)
    print(NSString(format: "%p", addr))
}

这不是 的重复问题。我问的是语言羽毛,另一个是编程技巧。

在你发表评论并对此有了更好的理解后,我将其加载到操场上,它似乎按预期工作

原答案供参考

要记住的一点是,结构基本上是内存中的数据块。当您创建 valueArray 时,一块内存被设置为其分配的值

当您创建 valueArray2 时,您正在创建该结构的一个新实例,这意味着它将拥有一个全新的内存块,然后您将设置 value 到 valueArray 中内存块的相同 value。这会导致在两个不同的内存位置复制数据。

这与对象相反,在这种情况下,valueArray 将是指向内存块的指针,而当您创建 valueArray2 时,它将创建指向同一内存块的新指针。

好吧,我做了很多实验,终于弄明白了。

  1. 我们不能使用 & 来获取数组地址,因为一旦我们这样做,Swift 将复制数组以更好地与 C 交互,使用 & 获取对象的相邻地址数组并改为进行数学运算。 或者使用lldb指令frame variable -L
  2. 一旦数组的任何值元素发生变化,就会复制整个数组。
  3. Array 的实际值元素分配在堆上。
  4. Swift也对元素为class.
  5. 的Array做了很多优化
  6. Swift 太棒了。

其实我写my first blog就是为了这个