美文网首页
Protocol - IteratorProtocol

Protocol - IteratorProtocol

作者: sasky2008 | 来源:发表于2020-12-11 09:55 被阅读0次
    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?
    }
    

    提供了遍历的能力, 支持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()

    相关文章

      网友评论

          本文标题:Protocol - IteratorProtocol

          本文链接:https://www.haomeiwen.com/subject/plohgktx.html