在尝试为RosettaCode在Swift中正确实现MergeSort算法时(目前列出了效率很低的解决方案),我发现了一个奇怪的行为。由于MergeSort需要将数组递归传递给函数,因此到目前为止,我最有效的实现方式不是传递数组本身(似乎无法轻易通过引用传递),而是传递该数组的ArraySlice视图。
Documentation的ArraySlice似乎指出ArraySlice不存储其数据,而只是提供基础数组的“视图”:
ArraySlice类型使您可以快速有效地对较大数组的各个部分执行操作。 不是将切片的元素复制到新的存储,而是ArraySlice实例提供了对更大阵列的存储的视图。并且由于ArraySlice提供与Array相同的接口,因此您通常可以执行相同的操作像在原始数组上一样对切片进行操作。
但是,用replaceSubrange
修改ArraySlice或设置其元素似乎并不影响我的原始数组。像本例一样:
// Create an array
var arr = [Int](repeating: 0, count: 5)
print("array:",arr) // original array
// Modify its ArraySlice
var slice = ArraySlice(arr) // or arr[0..<arr.count]
slice.replaceSubrange(1...3, with: [1,2,3])
slice[4] = 4
print("slice:",slice) // slice preserves all the changes
print("array:",arr) // but original array is not modified
// Modify Array directly
arr.replaceSubrange(1...3, with: [5,6,7])
print("array:",arr) // this time it is modified
输出:
array: [0, 0, 0, 0, 0]
slice: [0, 1, 2, 3, 4]
array: [0, 0, 0, 0, 0]
array: [0, 5, 6, 7, 0]
如您所见,修改ArraySlice会对其进行更改,但不会像我期望的那样修改我的原始数组。
问题是,为什么会发生?修改后的ArraySlice的基础存储是什么?特别是元素4
存放在哪里?