2017-04-24 64 views
3
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) 

報價:突變ArraySlice會實例化一個新的數組實例嗎?從蘋果

無論是firstHalf也不secondHalf片分配自己的任何新的存儲。相反,每個呈現缺席陣列的存儲視圖。

當我嘗試變異firstHalf如下所示:

firstHalf[1] = 19 

firstHalf變化的值,但原始數組absences保持相同(firstHalf[1]等於19而absences[1]等於2) 所以在後臺發生了什麼。我是否通過改變數組切片來實例化新數組? 在此先感謝。

+2

很可能由斯威夫特集合,在那裏,直到你嘗試變異它不會複製集合在幕後採用的典型的寫入時複製行爲。有關寫入時複製的討論,請參閱WWDC 2015視頻[使用值類型構建更好的應用](https://developer.apple.com/videos/play/wwdc2015/414/)。 – Rob

+0

這也是我腦海中浮現的東西。我只是想確定一下。感謝您的快速響應。 – Pink

回答

4

是的,標準庫的集合類型(包括ArrayArraySlice)都具有寫入時複製行爲。這意味着他們可以將分享存儲他們的元素與其他集合,直到他們發生了變異,在這種情況下,他們將採取他們自己的副本。

在你的情況下,切片firstHalf具有視圖上被非唯一地引用(如二者absences & secondHalf也有一個視圖在其上)的基礎數組緩衝器。因此,當您去突變firstHalf時,會觸發一個副本 - 創建包含該切片元素(但不一定是整個陣列)的緩衝區的新緩衝區

firstHalf現在有一個獨特的視圖到這個新的緩衝區,absences & secondHalf都共享一個視圖到舊的數組緩衝區。因此firstHalf現在可以改變其緩衝區的元素而不影響原始數組的元素,從而保留值語義。

+0

就像@Rob指出的那樣。大! – Pink

3

這是Swift集合在場景後面使用的標準寫時複製行爲,在這種情況下,它不會複製集合,直到您嘗試對其進行變異。有關寫入時複製的討論,請參閱WWDC 2015視頻Building Better Apps with Value Types in Swift

的意見in the code澄清這一點對我們來說:

/// Slices Share Indices 
/// -------------------- 
/// 
/// A collection and its slices share the same indices. An element of a 
/// collection is located under the same index in a slice as in the base 
/// collection, as long as neither the collection nor the slice has been 
/// mutated since the slice was created. 

... 

/// Slices Inherit Collection Semantics 
/// ----------------------------------- 
/// 
/// A slice inherits the value or reference semantics of its base collection. 
/// That is, when working with a slice of a mutable 
/// collection that has value semantics, such as an array, mutating the 
/// original collection triggers a copy of that collection, and does not 
/// affect the contents of the slice. 
+0

完美!謝謝。雖然我已經接受了Harnish的回答,但改變這種做法是不公平的,^^ – Pink

+0

@Pink我也不會要求你改變你接受的答案。我只是提供有關以前評論的支持文檔。 – Rob

+0

然後沒問題。乾杯! – Pink