Swift中的Array <t>,ContiguousArray <t>和ArraySlice <t>有什么区别?

时间:2015-07-08 10:54:33

标签: swift swift2

在Swift 2中,三种阵列变体之间的主要区别是什么:

  • 阵列
  • ContiguousArray
  • ArraySlice

任何人都可以用现实世界的例子来解释这个吗?

5 个答案:

答案 0 :(得分:12)

来自docs

<强> ContiguousArray:

  

效率等同于Array的效率,除非T是类或@objc协议类型,在这种情况下使用ContiguousArray可能更有效。但请注意,ContiguousArray不会桥接到Objective-C。有关更多详细信息,请参阅与ContiguousArray共享大多数属性的数组。

基本上,只要您在数组中存储 @objc协议类型,您可能需要考虑使用ContiguousArray而不是{{1 }}

<强> ArraySlice

  

ArraySlice始终使用连续存储,不会桥接到Objective-C。

     

警告:不鼓励长期存储ArraySlice实例

     

因为ArraySlice会在一些较大的存储上显示视图   即使在原始数组的生命周期结束之后,也存储切片   可能会延长不再可访问的元素的生命周期,   这表现为明显的记忆和物体泄漏。阻止   这个效果,只使用ArraySlice进行瞬态计算。

当您想要从数组中获取子范围时,大多数情况下都会使用ArraySlices,例如:

Array

您应该使用let numbers = [1, 2, 3, 4] let slice = numbers[Range<Int>(start: 0, end: 2)] //[1, 2]

的任何其他情况

答案 1 :(得分:1)

Swift定义了以下实现ArrayType协议的类; Array,ContiguousArray,Slice

Swift Array是表示数组的主类,该数组是一个采用1种类型的泛型类,整数数组的类型为Array<Int>,创建一个整数数组:

var myArray = Array<Int>()

Slice是一个带有内部实现的数组,它使得从数组顶部删除元素的计算成本低廉。以下内容在Slice类型上表现良好:

var arr = [1,2,3,4,5]
arr[1…4]

没有太多关于ContiguousArray的文档,但从其名称​​可以猜测它与内部数组存储有关,可能元素存储在连续内存分配布局中。

Read more.

答案 2 :(得分:1)

不同类别的Swift的好消息来源是:http://swiftdoc.org/

数组很清楚所以我们来谈谈其他两个。

ContiguousArray:http://swiftdoc.org/type/ContiguousArray/

  

快速,连续存储的T。

数组      

效率等同于Array的效率,除非T是一个类或   @objc协议类型,在这种情况下使用ContiguousArray可能更多   高效。但请注意,ContiguousArray不会桥接到   Objective-C的。请参阅与ContiguousArray共享最多的数组   属性,更多细节。

ArraySlice:http://swiftdoc.org/type/ArraySlice/

  

类似于Array的类型,表示任何Array的子​​序列,   ContiguousArray或其他ArraySlice。

     

ArraySlice始终使用连续存储,但不会桥接   目标C

简而言之:

当T是类或@objc协议类型时,ContiguousArray可以提高效率 ArraySlice用于表示子部分中的Array。

答案 3 :(得分:1)

Apple提供了新的文档。 https://git.io/vg5uw

所以,

  

ContiguousArray<Element>是三次使用中最快最简单的   这时你需要“C阵列”的表现。一个元素   ContiguousArray总是连续存储在内存中。

  

Array<Element>ContiguousArray<Element>类似,但针对此进行了优化   来自Cocoa的高效转换和返回时Element可以是一个类   类型,Array<Element>可以由(可能是非连续的)支持   存储任意NSArray而不是Swift   ContiguousArray。 Array<Element>也支持上传和下传   在相关类类型的数组之间。当已知Element是一个   非类型,Array<Element>的性能与此相同   ContiguousArray<Element>

答案 4 :(得分:0)

切片保持索引

这不是一个完整的答案。但是,Swift中带有少量gothcha的东西:

let array = [1,4,9,12,15]

您认为以下各项的值相同吗?

print(array[2..<5].index(of:12)) // is it 1 or 3?
print(array.index(of:12)) // 3

是的!因为两者都将打印3。这是因为ArraySlice将不会获得自己的唯一副本(除非Array发生了突变)。 ArraySlice基本上是一种查看同一Array的某些索引的方法。它不会创建[9,12,15]的新数组并对其进行调查。它只会查看原始数组的给定范围

现在怎么样?您认为以下内容是否相同?

print(array[2..<5].index(of:1)) // nil
print(array.index(of:1)) // 0

不! ArraySlice将打印nil,而Array将打印0

显然:

print(array[2..<4][2]) // 9
print(array[2..<4][0]) // ERROR: out of bounds

又一次令人惊讶:

print(array.dropFirst(2).index(of:15) 

不是不是 2。它将返回4作为其索引。为什么?因为dropFirst返回了ArraySlice。如果您不希望它维护索引,则应该在ArraySlice之外构造一个新的Array ...

编辑:

来自docs

  

与Array和ContiguousArray不同, ArraySlice的起始索引   实例并不总是为零。切片保持相同的索引   相同元素的较大数组,因此切片的起始索引   取决于它的创建方式,让您执行基于索引的   在完整阵列或切片上进行操作。

如果您对更多感兴趣。指向文档的链接还有另一个示例