Dart中是否存在类似C++的迭代器可直接修改集合内元素?
Dart 实现类似C++迭代器修改集合元素的方案
Dart 不存在与C++迭代器、左值引用完全对等的原生语义,其变量赋值默认走引用重绑定逻辑,无法通过直接给变量赋值修改集合内的原元素。但无需手动维护索引,可通过以下几种方案实现同等效果:
方案1:通用对象包装器(适配List、Map等所有集合场景)
Dart中类实例按引用传递,将业务对象封装到可修改的包装类中,拿到包装类的引用后,修改其内部的value字段即可同步修改集合内的元素,和C++操作迭代器的效果完全一致:
// 通用包装类定义 class Wrapper<T> { T value; Wrapper(this.value); } // 业务类示例 class Cannon { int firepower; Cannon(this.firepower); } class Ship { int durability; Cannon cannon; Ship(this.durability, this.cannon); } void main() { final playgroundMap = <(int, int), Wrapper<Ship>>{}; playgroundMap[(2,2)] = Wrapper(Ship(100, Cannon(50))); playgroundMap[(3,3)] = Wrapper(Ship(200, Cannon(60))); // 拿到包装类引用,等价于C++中获取迭代器 final shipWrapper = playgroundMap[(2,2)]!; // 修改属性直接生效 shipWrapper.value.cannon.firepower = 1000; // 替换整个对象也会同步更新集合内的元素 shipWrapper.value = Ship(200, Cannon(90)); // 验证修改结果 print(playgroundMap[(2,2)]!.value.durability); // 输出200 print(playgroundMap[(2,2)]!.value.cannon.firepower); // 输出90 }
方案2:保留Map键(仅适配Map场景)
如果你的使用场景和示例一致基于Map存储,无需额外封装,直接保留查询元素用的键即可,修改时通过键直接访问Map内的元素:
final playgroundMap = <(int, int), Ship>{}; playgroundMap[(2,2)] = Ship(100, Cannon(50)); // 保留键等价于C++中保存迭代器 final shipKey = (2,2); // 直接修改集合内元素 playgroundMap[shipKey]!.cannon.firepower = 1000; playgroundMap[shipKey] = Ship(200, Cannon(90));
注:若使用Dart 3.0以下版本,无法使用Record作为键,可自定义坐标类并重写
==与hashCode方法替代。
方案3:自定义List迭代器包装(仅适配List场景)
如果使用List存储,不想暴露索引,可自行封装迭代器类,内部持有List引用和对应索引,上层使用时无需感知索引存在:
// 自定义List迭代器 class ListIterator<T> { final List<T> _list; final int _index; ListIterator(this._list, this._index); T get value => _list[_index]; set value(T newValue) => _list[_index] = newValue; } void main() { final shipList = <Ship>[Ship(100, Cannon(50)), Ship(200, Cannon(60))]; // 获取迭代器,上层无需保存索引 final shipIter = ListIterator(shipList, 0); // 修改操作直接同步到List shipIter.value.cannon.firepower = 1000; shipIter.value = Ship(200, Cannon(90)); print(shipList[0].durability); // 输出200 }
内容的提问来源于stack exchange,提问作者mumboFromAvnotaklu
相关产品推荐
相关产品推荐

