首页 > 解决方案 > 用 replaceSubrange 修改 ArraySlice

问题描述

在尝试在 Swift 中为RosettaCode正确实现 MergeSort 算法(目前列出了一个非常低效的解决方案)时,我发现了一个奇怪的行为。由于 MergeSort 需要递归地将数组传递给函数,因此到目前为止我最有效的实现不是传递数组本身(似乎不能通过引用轻松传递),而是传递该数组的 ArraySlice 视图。

ArraySlice 的文档似乎指出 ArraySlice 不存储其数据,而仅提供底层数组的“视图”:

ArraySlice 类型使您可以快速高效地对较大数组的各个部分执行操作。ArraySlice 实例不是将切片的元素复制到新存储,而是将视图呈现到更大数组的存储上。而且由于 ArraySlice 提供与 Array 相同的接口,因此您通常可以对切片执行与原始数组相同的操作。

但是,使用或设置其元素修改 ArraySlicereplaceSubrange似乎不会影响我的原始数组。就像在这个例子中一样:

// 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存储在哪里?

标签: arraysswift

解决方案


推荐阅读