如何创建一个 Sequence
2018-04-09 本文已影响77人
Kare
Sequence
其实在coding中经常使用到,比如在使用 Array
,Set
, Dictionary
,这些数据类型中,就会使用到。
那么什么是 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
如果觉得我的做法不妥,欢迎指正。