Swift 中实现迭代器相关协议需要遵循两个协议:IteratorProtocol
和 Sequence
。
IteratorProtocol
协议定义了一个返回下一个元素的方法 next()
,并且要求实现者能存储当前元素的状态,以便在下一次调用 next()
时能够返回正确的元素。
protocol IteratorProtocol {
associatedtype Element
mutating func next() -> Element?
}
Sequence
协议则要求实现一个返回迭代器的 makeIterator()
方法。
protocol Sequence {
associatedtype Iterator: IteratorProtocol
func makeIterator() -> Iterator
}
通过同时遵循这两个协议,就能实现一个可迭代的数据类型,例如一个简单的自定义数组类型:
struct MyArray<Element>: IteratorProtocol, Sequence {
private var elements: [Element]
private var idx = 0
init(_ elements: [Element]) {
self.elements = elements
}
mutating func next() -> Element? {
guard idx < elements.count else {
return nil
}
defer { idx += 1 }
return elements[idx]
}
func makeIterator() -> MyArray<Element> {
return self
}
}
let arr = MyArray([1, 2, 3])
for element in arr {
print(element)
}
// 输出:
// 1
// 2
// 3
在上面的例子中,MyArray
同时遵循了 IteratorProtocol
和 Sequence
协议,并使用了一个私有变量 idx
来记录当前遍历的位置。在 next()
方法中,当遍历到最后一个元素时,返回 nil
表示遍历结束。在 makeIterator()
方法中,直接返回自身的实例,使得该类型本身就可以用 for-in 循环进行遍历。