一尘不染

变异ArraySlice会实例化一个新的数组实例吗?

swift

var absences = [0, 2, 0, 4, 0, 3, 1, 0]
let midpoint = absences.count / 2

var firstHalf = absences.prefix(upTo: midpoint)
let secondHalf = absences.suffix(from: midpoint)

苹果报价:

firstHalf切片和secondHalf切片都不分配自己的任何新存储。取而代之的是,每个视图都显示了不存在数组的存储视图。

当我尝试如下更改时firstHalf

firstHalf[1] = 19

firstHalf更改的值,但原始数组absences保持不变(firstHalf[1]等于19
absences[1]等于2),所以在后台发生了什么。我是否通过更改数组切片来实例化新数组?提前致谢。


阅读 210

收藏
2020-07-07

共1个答案

一尘不染

是的,标准库的集合类型(包括ArrayArraySlice)都具有写时复制行为。这意味着它们可以与其他集合 共享
其元素的存储,直到它们被突变为止,在这种情况下,他们将获得它们自己的副本。

在你的情况下,底层数组缓冲该切片firstHalf具有视图上被非唯一地引用(如二者absencessecondHalf也有一个视图在其上)。因此,当您进行mutate时firstHalf,将触发一个副本–创建一个包含切片元素(但不一定是
整个 数组)的 缓冲区。 __

firstHalf现在,在此新缓冲区上具有唯一的视图,并且absencessecondHalf都共享对旧数组缓冲区的视图。因此firstHalf,现在可以在不影响原始数组元素的情况下更改其缓冲区的元素,从而保留值的语义。

2020-07-07