4
作爲每Swift Documentation符合Collection
協議時:如何在常量時間內返回下標?
類型符合類別預期提供startIndex和endIndex的屬性和下標獲得的元件O(1)的操作。
下標如何在常量時間內返回?它不需要遍歷集合,直到正確的索引,然後返回該值嗎?
這是我使用符合Collection
LinkedList的:
indirect enum LinkedList<T> {
case value(element: T, next: LinkedList<T>)
case end
}
extension LinkedList: Sequence {
func makeIterator() -> LinkedListIterator<T> {
return LinkedListIterator(current: self)
}
var underestimatedCount: Int {
var count = 0
for _ in self {
count += 1
}
return count
}
}
struct LinkedListIterator<T>: IteratorProtocol {
var current: LinkedList<T>
mutating func next() -> T? {
switch current {
case let .value(element, next):
current = next
return element
case .end:
return nil
}
}
}
這裏是這是我真正符合協議:
extension LinkedList: Collection {
typealias Index = Int
typealias Element = T
var startIndex: Index {
return 0
}
var endIndex: Index {
return underestimatedCount
}
func index(after i: Index) -> Index {
return (i < endIndex) ? i + 1 : endIndex
}
subscript (position: Index) -> Element {
precondition(position < endIndex && position >= startIndex)
var iterator = makeIterator()
for i in 0 ..< position {
iterator.next()
if i + 1 == position {
return iterator.next()!
}
}
var zero = makeIterator()
return zero.next()!
}
}
let test = LinkedList<Int>.value(element: 2, next: LinkedList<Int>.value(element: 4, next: LinkedList<Int>.value(element: 7, next: LinkedList<Int>.value(element: 9, next: LinkedList<Int>.end))))
你可以看看[收藏的源代碼(https://github.com/apple/swift/blob/master/stdlib/public/core/ Collection.swift)來看看它是如何在Swift中實現的。關於該主題的更實用,更少理論性的教程,您還可以查看[本文由raywenderlich](https://www.raywenderlich.com/139591/building-custom-collection-swift) –
請注意,「低估的計數」應該也是O(1)。 –
'Collection'方法的默認實現假定O(1)下標,所以如果你讓你的'LinkedList'符合'Collection',你會發現其中一些太慢了。 – OOPer