public protocol IteratorProtocol {
/// The type of element traversed by the iterator.
associatedtype Element
/// Advances to the next element and returns it, or `nil` if no next element
/// exists.
///
/// Repeatedly calling this method returns, in order, all the elements of the
/// underlying sequence. As soon as the sequence has run out of elements, all
/// subsequent calls return `nil`.
///
/// You must not call this method if any other copy of this iterator has been
/// advanced with a call to its `next()` method.
///
/// The following example shows how an iterator can be used explicitly to
/// emulate a `for`-`in` loop. First, retrieve a sequence's iterator, and
/// then call the iterator's `next()` method until it returns `nil`.
///
/// let numbers = [2, 3, 5, 7]
/// var numbersIterator = numbers.makeIterator()
///
/// while let num = numbersIterator.next() {
/// print(num)
/// }
/// // Prints "2"
/// // Prints "3"
/// // Prints "5"
/// // Prints "7"
///
/// - Returns: The next element in the underlying sequence, if a next element
/// exists; otherwise, `nil`.
mutating func next() -> Self.Element?
}
Conforming Types
AnyIterator, CollectionOfOne.Iterator, Dictionary.Iterator, DropWhileSequence.Iterator, EmptyCollection.Iterator, EnumeratedSequence.Iterator, FlattenSequence.Iterator, IndexingIterator, IteratorSequence, JoinedSequence.Iterator, LazyDropWhileSequence.Iterator, LazyFilterSequence.Iterator, LazyMapSequence.Iterator, LazyPrefixWhileSequence.Iterator, PrefixSequence.Iterator, ReversedCollection.Iterator, Set.Iterator, StrideThroughIterator, StrideToIterator, UnfoldSequence, UnsafeBufferPointer.Iterator, UnsafeRawBufferPointer.Iterator, Zip2Sequence.IteratorAssociated Types
associatedtype -
Element
提供了遍历的能力, 支持for in. 是数组的基础。
也就是Sequence 和 Collection的基础。
合理运用可以提高很多效率, 比如尾随闭包提供条件进行数据处理。
extension Sequence {
func condition(_ nextResult: (Element, Element) -> Element) -> Element? {
// 获取数据流
var i = makeIterator()
guard var accumulated = i.next() else {
return nil
}
while let element = i.next() {
accumulated = nextResult(accumulated, element)
}
return accumulated
}
}
if let max = [1, 2, 4, 3].condition { (value, value1) -> Int in
return value > value1 ? value : value1
} {
print(max)
}
// print 4
比较推荐动手写一下, 下面的代码, 很有趣。
struct CountDown: Sequence {
let start: Int
func makeIterator() -> CountdownIterator {
return CountdownIterator(self)
}
}
struct CountdownIterator: IteratorProtocol {
let countDown: CountDown
init(_ countDown: CountDown ) {
self.countDown = countDown
}
var times = 0
mutating func next() -> Int? {
let nextNumber = countDown.start - times
guard nextNumber > 0 else {
return nil
}
times += 1
return nextNumber
}
}
let fourToOne = CountDown(start: 4)
fourToOne.forEach { print($0) }
// print
// 4
// 3
// 2
// 1
当然也可以手动调用 .next()