在Swift 2中,三种数组变体之间的主要区别是什么:
有人能用一个真实的世界的例子来解释这一点吗?
j2qf4p5b1#
关于docs:
ContiguousArray:
效率等同于Array,除非T是class或@objc协议类型,在这种情况下使用ContiguousArray可能更有效。但是,请注意,ContiguousArray并不桥接到Objective-C。有关更多详细信息,请参见Array,ContiguousArray与Array共享大多数属性。基本上,每当你在数组中存储classes或**@objc protocol**类型时,你可能需要考虑使用ContiguousArray而不是Array。
ContiguousArray
Array
数组切片
ArraySlice始终使用连续存储,并且不会桥接到Objective-C。警告:不建议长期存储ArraySlice示例因为即使在原始阵列的生命周期结束之后,ArraySlice也会呈现对某个较大阵列的存储的视图,所以存储切片可能会延长不再可访问的元素的生命周期,这可能表现为明显的内存和对象泄漏。为了防止这种影响,请仅将ArraySlice用于 transient 计算。ArraySlice在大多数情况下用于从Array中获取子范围,例如:
let numbers = [1, 2, 3, 4] let slice = numbers[Range<Int>(start: 0, end: 2)] //[1, 2]
字符串在其他情况下,您应该使用Array。
yzxexxkh2#
关于Swift不同类的好源代码是:http://swiftdoc.org/数组非常清楚,所以我们来谈谈另外两个。连续阵列:http://swiftdoc.org/type/ContiguousArray/的一种快速连续存储的T.效率等同于Array,除非T是class或@objc协议类型,在这种情况下使用ContiguousArray可能更有效。但是,请注意,ContiguousArray并不桥接到Objective-C。有关更多详细信息,请参见Array,ContiguousArray与Array共享大多数属性。ArraySlice:http://swiftdoc.org/type/ArraySlice/类数组类型,表示任意Array、ContiguousArray或其他ArraySlice的子序列。ArraySlice始终使用连续存储,并且不会桥接到Objective-C。简而言之:当T是类或@objc协议类型时,ContiguousArray是为了更高的效率,ArraySlice将在子部分中表示Array。
wdebmtf23#
苹果的新文档。https://git.io/vg5uw所以ContiguousArray<Element>是这三种方法中最快、最简单的一种,当你需要“C数组”性能时,就可以使用它。ContiguousArray的元素始终连续存储在内存中。.Array<Element>类似于ContiguousArray<Element>,但优化了从可可和back的高效转换-当Element可以是类类型时,Array<Element>可以由任意NSArray的(可能不连续的)存储支持,而不是Swift ContiguousArray。Array<Element>还支持相关类类型数组之间的向上和向下转换。当已知Element是非类类型时,Array<Element>的性能与ContiguousArray<Element>的性能相同。
ContiguousArray<Element>
Array<Element>
r8uurelv4#
Swift定义了以下实现ArrayType协议的类;Array、ContiguousArray、Slice。Swift Array是表示数组的主类,数组是一个泛型类,它采用1类型,整数数组的类型为Array<Int>,创建一个整数数组:
Array<Int>
var myArray = Array<Int>()
字符串Slice是一个内部实现的数组,使得从数组顶部移除元素在计算上便宜。以下内容将在切片类型上执行良好:
var arr = [1,2,3,4,5] arr[1…4]
型关于ContiguousArray的文档不多,但从它的名字可以猜到它与内部阵列存储有关,可能元素存储在ContiguousArray布局中。Read more.
dddzy1tm5#
这不是一个完整的答案。但有一点来自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]并查看它。它只会查看原始数组的给定范围。现在这个怎么样?您认为以下的值是否相同?
3
print(array[2..<5].index(of:1)) // nil print(array.index(of:1)) // 0
型否!ArraySlice将打印nil,而Array将打印0很明显:
nil
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。编辑:
2
4
ArraySlice
从docs:与Array和ContiguousArray不同,ArraySlice示例的起始索引并不总是零。切片为相同元素维护较大数组的相同索引,因此切片的起始索引取决于它的创建方式,允许您对完整数组或切片执行基于索引的操作。如果你有兴趣的话。文档的链接还有另一个例子
f8rj6qna6#
这里发生的事情是,Swift设计师正在创建一些并不真正有用的东西。ArraySlice范例使得在没有“起始”索引的情况下跨一个编码的字符串值并提取单个片段变得非常困难,因此您最终会得到代码,在传递一个切片的函数中,必须创建自己的索引值,从切片的起始索引开始,然后用习惯于其他语言的人不熟悉的表达式和概念在切片中前进,其他数组或集合数据结构。解析一个字符串并从中提取字符,并计算字符的ascii数值变得非常困难。
6条答案
按热度按时间j2qf4p5b1#
关于docs:
ContiguousArray:
效率等同于Array,除非T是class或@objc协议类型,在这种情况下使用ContiguousArray可能更有效。但是,请注意,ContiguousArray并不桥接到Objective-C。有关更多详细信息,请参见Array,ContiguousArray与Array共享大多数属性。
基本上,每当你在数组中存储classes或**@objc protocol**类型时,你可能需要考虑使用
ContiguousArray
而不是Array
。数组切片
ArraySlice始终使用连续存储,并且不会桥接到Objective-C。
警告:不建议长期存储ArraySlice示例
因为即使在原始阵列的生命周期结束之后,ArraySlice也会呈现对某个较大阵列的存储的视图,所以存储切片可能会延长不再可访问的元素的生命周期,这可能表现为明显的内存和对象泄漏。为了防止这种影响,请仅将ArraySlice用于 transient 计算。
ArraySlice在大多数情况下用于从Array中获取子范围,例如:
字符串
在其他情况下,您应该使用
Array
。yzxexxkh2#
关于Swift不同类的好源代码是:http://swiftdoc.org/
数组非常清楚,所以我们来谈谈另外两个。
连续阵列:http://swiftdoc.org/type/ContiguousArray/的
一种快速连续存储的T.
效率等同于Array,除非T是class或@objc协议类型,在这种情况下使用ContiguousArray可能更有效。但是,请注意,ContiguousArray并不桥接到Objective-C。有关更多详细信息,请参见Array,ContiguousArray与Array共享大多数属性。
ArraySlice:http://swiftdoc.org/type/ArraySlice/
类数组类型,表示任意Array、ContiguousArray或其他ArraySlice的子序列。
ArraySlice始终使用连续存储,并且不会桥接到Objective-C。
简而言之:
当T是类或@objc协议类型时,ContiguousArray是为了更高的效率,ArraySlice将在子部分中表示Array。
wdebmtf23#
苹果的新文档。https://git.io/vg5uw
所以
ContiguousArray<Element>
是这三种方法中最快、最简单的一种,当你需要“C数组”性能时,就可以使用它。ContiguousArray的元素始终连续存储在内存中。.
Array<Element>
类似于ContiguousArray<Element>
,但优化了从可可和back的高效转换-当Element可以是类类型时,Array<Element>
可以由任意NSArray的(可能不连续的)存储支持,而不是Swift ContiguousArray。Array<Element>
还支持相关类类型数组之间的向上和向下转换。当已知Element是非类类型时,Array<Element>
的性能与ContiguousArray<Element>
的性能相同。r8uurelv4#
Swift定义了以下实现ArrayType协议的类;Array、ContiguousArray、Slice。
Swift Array是表示数组的主类,数组是一个泛型类,它采用1类型,整数数组的类型为
Array<Int>
,创建一个整数数组:字符串
Slice是一个内部实现的数组,使得从数组顶部移除元素在计算上便宜。以下内容将在切片类型上执行良好:
型
关于ContiguousArray的文档不多,但从它的名字可以猜到它与内部阵列存储有关,可能元素存储在ContiguousArray布局中。
Read more.
dddzy1tm5#
切片维护索引
这不是一个完整的答案。但有一点来自Swift的gothcha:
字符串
您认为以下的值是否相同?
型
是的!这两个都可以打印
3
。这是因为ArraySlice不会获得自己唯一的副本(除非Array被变异)。ArraySlice基本上是一种查看同一Array的特定索引的方法。它不会创建一个新的数组[9,12,15]并查看它。它只会查看原始数组的给定范围。现在这个怎么样?您认为以下的值是否相同?
型
否!ArraySlice将打印
nil
,而Array将打印0
很明显:
型
令人惊讶的是:
型
不是
2
。它将返回4
作为索引。为什么?因为dropFirst返回ArraySlice
。如果你不想让它维护索引,那么你应该构造一个新的数组出来的ArraySlice。编辑:
从docs:
与Array和ContiguousArray不同,ArraySlice示例的起始索引并不总是零。切片为相同元素维护较大数组的相同索引,因此切片的起始索引取决于它的创建方式,允许您对完整数组或切片执行基于索引的操作。
如果你有兴趣的话。文档的链接还有另一个例子
f8rj6qna6#
这里发生的事情是,Swift设计师正在创建一些并不真正有用的东西。ArraySlice范例使得在没有“起始”索引的情况下跨一个编码的字符串值并提取单个片段变得非常困难,因此您最终会得到代码,在传递一个切片的函数中,必须创建自己的索引值,从切片的起始索引开始,然后用习惯于其他语言的人不熟悉的表达式和概念在切片中前进,其他数组或集合数据结构。
解析一个字符串并从中提取字符,并计算字符的ascii数值变得非常困难。