Swift 如何实现 迭代器相关协议

26 min read

Swift 中实现迭代器相关协议需要遵循两个协议:IteratorProtocolSequence

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 同时遵循了 IteratorProtocolSequence 协议,并使用了一个私有变量 idx 来记录当前遍历的位置。在 next() 方法中,当遍历到最后一个元素时,返回 nil 表示遍历结束。在 makeIterator() 方法中,直接返回自身的实例,使得该类型本身就可以用 for-in 循环进行遍历。