IteratorProtocol 是 Swift 中定义的一个协议,表示一个可以逐步生成序列中每个元素的对象。与 Sequence 协议配合使用,IteratorProtocol 是生成序列中每个元素的核心组件。
基本定义
IteratorProtocol 的定义如下:
protocol IteratorProtocol {
associatedtype Element
mutating func next() -> Element?
}
associatedtype Element
定义了 Iterator 所要生成的元素类型。
mutating func next() -> Element?
这个方法是 Iterator 的核心。
每次调用 next() 时,返回序列中的下一个元素。
如果序列已经耗尽,返回 nil,表示迭代结束。
如何使用
1、与 Sequence 配合使用
Sequence 通过 makeIterator() 方法返回一个实现了 IteratorProtocol 的对象。
调用迭代器的 next() 方法,可以逐步获取序列中的每个元素。
2、直接实现 IteratorProtocol
自定义一个迭代器,来控制序列的生成方式。
简单示例
1、手动实现一个迭代器
struct CountdownIterator: IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count > 0 {
defer { count -= 1 }
return count
} else {
return nil
}
}
}
// 使用示例
var iterator = CountdownIterator(count: 5)
while let number = iterator.next() {
print(number) // 输出:5 4 3 2 1
}
说明:
count 是迭代器的状态,表示当前迭代到哪里。
每次调用 next():
如果还有剩余元素,返回当前的 count,然后将其减 1。
如果 count 为 0,返回 nil。
2、自定义序列 + 迭代器
如果想让一个类型支持迭代,通常需要同时实现 Sequence 和 IteratorProtocol。
struct Countdown: Sequence {
let start: Int
func makeIterator() -> CountdownIterator {
return CountdownIterator(count: start)
}
}
// 使用示例
let countdown = Countdown(start: 5)
for number in countdown {
print(number) // 输出:5 4 3 2 1
}
与 Sequence 的关系
Sequence 是一组元素的集合,表示整体。
IteratorProtocol 是获取序列中元素的方式。
Sequence 协议要求实现 makeIterator() 方法来返回一个实现了 IteratorProtocol 的迭代器对象。
标准库中的迭代器
Swift 标准库中许多类型的迭代器都遵守了 IteratorProtocol,例如:
1、数组的迭代器
let array = [1, 2, 3]
var iterator = array.makeIterator()
while let value = iterator.next() {
print(value) // 输出:1 2 3
}
2、字典的迭代器
let dictionary = ["a": 1, "b": 2]
var dictIterator = dictionary.makeIterator()
while let (key, value) = dictIterator.next() {
print("\(key): \(value)")
}
重要特性
1、状态依赖
IteratorProtocol 的实现通常是有状态的。
每次调用 next() 后,迭代器的状态会发生变化。
2、惰性评估
迭代器仅在调用 next() 时生成元素,不会提前生成所有元素。
3、单次迭代
迭代器通常是一次性使用的,不能重置。
如果需要重新迭代,应该创建一个新的迭代器。
典型应用场景
1、自定义生成规则的序列
例如,生成一个无限序列或按特定规则生成的序列。
struct FibonacciIterator: IteratorProtocol {
var current = 0
var nextValue = 1
mutating func next() -> Int? {
defer {
let newNext = current + nextValue
current = nextValue
nextValue = newNext
}
return current
}
}
let fibIterator = FibonacciIterator()
print(Array(fibIterator.prefix(10))) // 输出:前 10 个斐波那契数
2、惰性处理大型数据
使用迭代器逐步处理,而不是一次性加载到内存中。