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)
来自苹果的引述:
Neither the firstHalf nor secondHalf slices allocate any new storage of their own. Instead, each presents a view onto the storage of the absences array.
当我尝试按如下方式改变 firstHalf
时:
firstHalf[1] = 19
firstHalf
的值发生变化,但原始数组 absences
保持不变(firstHalf[1]
等于 19,而 absences[1]
等于 2)
那么在后台发生了什么。我是否通过改变数组切片来实例化一个新数组?
提前致谢。
最佳答案
是的,标准库的集合类型,包括Array
和ArraySlice
,都具有写时复制行为。这意味着它们可以与其他集合共享它们的元素存储,直到它们发生变异,在这种情况下,它们将获取它们自己的副本。
在您的情况下,切片 firstHalf
具有 View 的底层数组缓冲区是非唯一引用的(因为 absences
和 secondHalf
也可以看到它)。因此,当您改变 firstHalf
时,会触发一个副本——创建一个包含切片元素(但不一定是整个)的新缓冲区大批)。
firstHalf
现在对这个新缓冲区有独特的看法,absences
和 secondHalf
都共享对旧数组缓冲区的看法。因此 firstHalf
现在可以在不影响原始数组元素的情况下改变其缓冲区的元素,从而保留值语义。
关于arrays - 改变 ArraySlice 会实例化一个新的数组实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43589637/