美文网首页
如何创建一个 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