美文网首页
如何创建一个 Sequence

如何创建一个 Sequence

作者: Kare | 来源:发表于2018-04-09 00:00 被阅读77次

    Sequence 其实在coding中经常使用到,比如在使用 ArraySetDictionary,这些数据类型中,就会使用到。

    那么什么是 Sequence 呢?

    Sequence 是一系列相同数据的集合,并且具有迭代能力。

    常见的 Sequence 是 for _ in ... 循环了,它会遍历整个要输出的对象。

    let lists = [...]
    for list in lists {
        print(list)
    }
    

    这是常见的一个循环 lists 集合的例子,他会依次输出lists中的值。

    为什么他们具有迭代输出的能力了,原因是他们遵循了 Sequence 协议

    Sequence 协议部分内容

    associatedtype Iterator : IteratorProtocol
    public func makeIterator() -> Self.Iterator
    
    • 这个方法要求返回一个 Iterator ,Iterator是一个 IteratorProtocol 协议

    IteratorProtocol 协议内容

    associatedtype Element
    public mutating func next() -> Self.Element?
    
    • 这个方法会持续返回基础序列中的下一个值,否则返回 nil

    那么也就是说,如果我们要自己实现一个 Sequence ,必须要遵循两点

    • 实现 makeIterator() 方法
    • 创造一个IteratorProtocol的实现

    其实一个数组的运行过程也就是一下代码:

    let result = books.makeIterator()
    while let rs = result.next() {}
    

    在数组遍历时,流程大概也可以推测出来

    • 首先数组调用了 makeIterator() 方法
    • 然后再去调用 next() 方法

    在 Swift4.1 中,我使用以下方法也能达成一个 Sequence

    struct Books: Sequence, IteratorProtocol {
        let names: [String]
        private var idx = 0
        
        init(names: [String]) {
            self.names = names
        }
        
        mutating func next() -> String? {
            guard idx < names.count else {
                return nil
            }
            defer {
                idx += 1
            }
            return names[idx]
        }
    }
    

    此方法值得注意的是

    • 我把 idx当前下标值 私有化,因为是我不想在初始化使用时,外部去干扰内部的idx
    • 在初始化时只传入书名称 定义了一个方法 init(names: [String])

    最后的调用

    func showResult() {
        for result in Books(names: ["A", "B", "C", "D"]) {
            print(result)
        }
    }
    // A
    // B
    // C
    // D
    

    如果觉得我的做法不妥,欢迎指正。

    相关文章

      网友评论

          本文标题:如何创建一个 Sequence

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