为什么Swift标准库中的reverse()函数返回ReverseRandomAccessCollection?

Bry*_*jar 19 arrays standard-library swift

现在我已经学会了Swift(达到一个合理的水平),我正试图掌握标准库,但实际上它主要是ελληνικά给我!

所以一个特定的问题:我有一个字符串数组,我可以调用reverse().

let arr = ["Mykonos", "Rhodes", "Naxos"].reverse()
Run Code Online (Sandbox Code Playgroud)

现在天真地我以为我会从中找回一种类型的阵列.(例如Ruby有一个类似的方法,你传递一个数组并返回一个数组)

但arr现在实际上是类型

ReverseRandomAccessCollection<Array<String>>
Run Code Online (Sandbox Code Playgroud)

这实际上是一个符合CollectionType的结构:

public struct ReverseRandomAccessCollection<Base : CollectionType where Base.Index : RandomAccessIndexType> : _ReverseCollectionType
Run Code Online (Sandbox Code Playgroud)

这意味着我可以这样做:

for item in arr {
  print(item)
}
Run Code Online (Sandbox Code Playgroud)

但我不能这样做

print(arr[0])
Run Code Online (Sandbox Code Playgroud)

为什么这样设计成这样?

Swift中的字典也实现了CollectionType,所以我可以这样做:

let dict = ["greek" : "swift sometimes", "notgreek" : "ruby for this example"].reverse()
Run Code Online (Sandbox Code Playgroud)

但字典不像数组一样排序,为什么我可以在dicts上调用reverse()?

奖励积分如果有人能指出我可以阅读的方向并改善我的Swift stdlib foo,Ευχαριστώ!

Mar*_*n R 27

它是时间和内存的性能优化.所述ReverseRandomAccessCollection呈现以相反的顺序原始数组的元素,而不需要创建一个新的数组 和复制的所有元素(只要原始阵列不被突变).

可以使用下标访问reverse元素:

let el0 = arr[arr.startIndex]
let el2 = arr[arr.startIndex.advancedBy(2)]
Run Code Online (Sandbox Code Playgroud)

要么

for i in arr.indices {
    print(arr[i])
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用显式创建数组

let reversed = Array(["Mykonos", "Rhodes", "Naxos"].reversed())
Run Code Online (Sandbox Code Playgroud)

一个字典也键/值对的序列.在

let dict = ["greek" : "swift sometimes", "notgreek" : "ruby for this example"].reverse()
Run Code Online (Sandbox Code Playgroud)

一种完全不同的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]
}
Run Code Online (Sandbox Code Playgroud)

结果是一个数组,其字典的键/值对的顺序相反.但这种用途有限,因为字典中键/值对的顺序可以是任意的.

  • 集合所具有的索引类型决定了您如何在集合上移动。所有集合都有前向索引 - 您可以从 `startIndex` 开始,调用 `.successor()` 直到到达 `endIndex`,但您不能向后移动索引(包括从 `endIndex` 开始 - 所以您可以' t 从末尾开始并移回到前面)。下一个级别是双向索引,它添加了“.predecessor()”方法。在那里您可以向后移动,因此您可以从“endIndex”开始并向后移动。这就是允许“ReverseCollection”包装集合并延迟提供其反向版本的原因。 (2认同)