如何在不调用moveNext的情况下判断Dart Iterator是否有当前值?
Dart Iterator 判断当前值是否可用的替代方案
- 用Expando给Iterator附加状态
Expando能给任意对象动态添加属性,不用修改原有类结构。可以给Iterator写个扩展,用Expando存储当前是否有可用值的状态,重写moveNext时更新状态,再新增hasCurrent方法查询:
final _iteratorActive = Expando<bool>(); extension IteratorWithHasCurrent<T> on Iterator<T> { bool get hasCurrent { return _iteratorActive[this] ?? false; } @override bool moveNext() { final result = super.moveNext(); _iteratorActive[this] = result; return result; } }
使用时,只要通过这个扩展调用moveNext,hasCurrent就会同步状态,且无额外移动副作用。注意:如果直接调用迭代器原生的moveNext,状态不会更新,要确保所有调用都走扩展方法。
- 实现带状态的通用Iterator包装类
如果不想用Expando,可以写个通用的包装Iterator,内置isActive状态,再给Iterable加个扩展方法返回包装后的实例。这种包装器通用且侵入性低,能避免你之前遇到的问题:
class StatefulIterator<T> implements Iterator<T> { final Iterator<T> _inner; bool _isActive = false; StatefulIterator(this._inner); bool get isActive => _isActive; @override T get current => _inner.current; @override bool moveNext() { _isActive = _inner.moveNext(); return _isActive; } } extension StatefulIterable<T> on Iterable<T> { Iterable<T> toStateful() sync* { final iterator = StatefulIterator(this.iterator); while (iterator.moveNext()) { yield iterator.current; } } }
使用示例:
var list = [1,2,3]; var iterator = list.toStateful().iterator; iterator.moveNext(); // 返回true,isActive为true print(iterator.isActive); // true print(iterator.current); // 1
- 外部维护迭代状态
如果以上方案都不想用,最直接的方式是在使用迭代器时,自己手动维护一个状态变量,每次调用moveNext后把结果存入变量,后续直接查询这个变量即可:
var iterator = [1,2,3].iterator; bool hasCurrent = false; hasCurrent = iterator.moveNext(); if (hasCurrent) { print(iterator.current); // 1 } // 直接查询hasCurrent就能知道当前是否有可用值 print(hasCurrent); // true hasCurrent = iterator.moveNext(); // ...
这个方案无需修改或包装迭代器,适合局部使用迭代器的场景。
内容的提问来源于stack exchange,提问作者Martin East
相关产品推荐
相关产品推荐

