现在我已经学会了Swift(达到一个合理的水平)我正试图掌握标准库,但事实上它主要是ελληνικά给我!
所以一个特定的问题:我有一个字符串数组,我可以在其上调用reverse()。
let arr = ["Mykonos", "Rhodes", "Naxos"].reverse()
现在天真地我以为我会从中找回一种类型的数据。 (例如Ruby有一个类似的方法,你传递一个数组并返回一个数组)
但是arr现在实际上是
类型ReverseRandomAccessCollection<Array<String>>
实际上是一个符合CollectionType的结构:
public struct ReverseRandomAccessCollection<Base : CollectionType where Base.Index : RandomAccessIndexType> : _ReverseCollectionType
这意味着我可以这样做:
for item in arr {
print(item)
}
但我做不到
print(arr[0])
为什么设计成这种方式?
Swift中的字典也实现了CollectionType,所以我可以这样做:
let dict = ["greek" : "swift sometimes", "notgreek" : "ruby for this example"].reverse()
但字典不像数组那样排序,为什么我可以在dicts上调用reverse()?
奖励积分如果有人能指出我可以阅读的方向并改善我的Swift stdlib foo,Ευχαριστώ!
答案 0 :(得分:27)
这是时间和内存的性能优化。
ReverseRandomAccessCollection
表示了元素
原始数组的顺序相反,无需创建新数组
并复制所有元素(只要原始数组不是
突变)。
你可以使用下标访问反向元素:
let el0 = arr[arr.startIndex]
let el2 = arr[arr.startIndex.advancedBy(2)]
或
for i in arr.indices {
print(arr[i])
}
您还可以使用
显式创建数组let reversed = Array(["Mykonos", "Rhodes", "Naxos"].reversed())
词典也是键/值对的序列。在
let dict = ["greek" : "swift sometimes", "notgreek" : "ruby for this example"].reverse()
调用完全不同的reversed()
方法:
extension SequenceType {
/// Return an `Array` containing the elements of `self` in reverse
/// order.
///
/// Complexity: O(N), where N is the length of `self`.
@warn_unused_result
public func reversed() -> [Self.Generator.Element]
}
结果是一个包含字典键/值对的数组 以相反的顺序。但这是有限的使用,因为订单 字典中的键/值对可以是任意的。
答案 1 :(得分:3)
来自language docs of ReverseCollention
(.reverse()
的结果):
当应用于具有的集合时,reverse()方法始终是惰性的 双向指数,但不暗示赋予懒惰 算法应用于其结果。
换句话说,对于具有双向索引的普通集合c:
- c.reverse()执行不创建新存储空间
...
因此,您可以将ReverseRandomAccessCollection
视为尚未反转的数组的随机访问包装(即原始数组arr
尚未被复制和撤消到记忆中的新位置。)
当然,从上面开始,你不能直接索引反向集合,因为Array
提供访问作为指向保存数组的内存的指针,索引对应于按位进行(取决于类型)在记忆中前进。但是,我们仍然可以使用ReverseRandomAccessIndex
访问数组索引样式中的“反向数组”元素:
let arr = ["Mykonos", "Rhodes", "Naxos"]
let arrReverse = arr.reverse()
/* ReverseRandomAccessCollection access "wrapper" over
the 'arr' data in memory. No new storage allocated */
let myIndex = arrReverse.startIndex.advancedBy(2)
/* bIndex type:
ReverseRandomAccessIndex<ReverseRandomAccessIndex<Index>> */
print(arrReverse[myIndex]) // "Mykonos"
相反,我们可以为反向数组显式分配内存,并将其视为任何其他数组。此时,arrReverse
是一个独立的数组,而不是arr
,除了(一次)使用它之外与前者无关。
let arr = ["Mykonos", "Rhodes", "Naxos"]
let arrReverse = Array(arr.reverse())
/* Array<String> */
let myIndex = arrReverse.startIndex.advancedBy(2)
/* bIndex type: Int */
print(arrReverse[myIndex]) // "Mykonos"
Martin R打败了我,所以请看他关于词典的说明。
答案 2 :(得分:1)
使用Swift 3.0,您可以通过索引直接访问Array值。
var streets = ["Albemarle", "Brandywine", "Chesapeake"]
streets = streets.reversed()
print("Array at index is \(streets[0])")
这将打印“切萨皮克”