迭代器工作原理
具体的细节可以看官方文档
其中使用到两个数据结构
Iterable
Iterator
该类是一个泛型基类,所以可以完成任意数据的迭代
其中最重要的是next方法,迭代过程中会返回Some值,迭代到末尾会返回None。
for in 工作原理
通常我们会使用如下的代码遍历数组集合。这里面其实就使用到了迭代器
let list = [1, 2, 3]
for (i in list) {
println(i)
}
它等价于以下代码
- Array 遵循接口 Iterable,我们通过iterator获取ArrayIterator迭代器
- 在while循环内,不断地调用next方法取值
- 取到最后返回None,结束while循环
let list = [1, 2, 3]
var it = list.iterator()
while (true) {
match (it.next()) {
case Some(i) => println(i)
case None => break
}
}
不过我更倾向于while let语法进行遍历
原理和上面的过程一样,只不过代码更简洁,在取值的过程中使用了模式匹配
let list = [1, 2, 3]
var it = list.iterator()
while (let Some(i) <- it.next()) {
println(i)
}
自定义迭代器
- 自定义类MyClass遵守接口Iterable,返回一个自定义迭代器MyIterator
- 自定义MyIterator遵守接口Iterator,实现next方法并在内部维护迭代的下标
import std.collection.{ArrayList, HashSet, HashMap}
// 一个迭代器,内部维护迭代的次数,保存需要迭代的数据
class MyIteratorClass<T> <: Iterator<T> {
var index: Int = 0
private let dataList: Array<T>
init(dataList: Array<T>) {
this.dataList = dataList
}
public func next(): Option<T> {
let v = dataList.get(index)
index += 1
return v
}
}
// 自定义可迭代的类
class MyIterableClass<T> <: Iterable<T> {
let list: Array<T>
let name: String = 'MyIterableClass'
init(list: Array<T>) {
this.list = list
}
// 需要返回一个迭代器用来迭代数据
// 这里迭代的数据是this.list
public func iterator(): Iterator<T> {
MyIteratorClass(this.list)
}
}
func demo() {
let list = Array(80) {i => i}
let myCls = MyIterableClass(list)
// 迭代器赋值
let a: Iterable<Int64> = myCls
for (i in myCls) {
println('for-in myCls ${i}')
}
}