【发布时间】:2023-03-10 20:12:01
【问题描述】:
我很清楚,迭代向量不应该让循环体任意改变向量。这可以防止容易出现错误的迭代器失效。
但是,并非所有类型的突变都会导致迭代器失效。请参阅以下示例:
let mut my_vec: Vec<Vec<i32>> = vec![vec![1,2], vec![3,4], vec![5,6]];
for inner in my_vec.iter_mut() { // <- or .iter()
// ...
my_vec[some_index].push(inner[0]); // <-- ERROR
}
这样的突变不会使my_vec 的迭代器失效,但是它是不允许的。它可能会使对 my_vec[some_index] 中特定元素的任何引用无效,但我们无论如何都不会使用任何此类引用。
我知道这些问题很常见,我不想解释。我正在寻找一种方法来重构它,以便我可以摆脱这个循环。在我的实际代码中,我有一个巨大的循环体,除非我很好地表达这一点,否则我无法对其进行模块化。
到目前为止我的想法:
- 用
Rc<RefCell<...>>包装向量。我认为这在运行时仍然会失败,因为RefCell会被迭代器借用,然后在循环体尝试借用它时会失败。 - 使用临时向量来累积未来的推送,并在循环结束后推送它们。这没关系,但需要比动态推送更多的分配。
- 不安全的代码,和指针乱七八糟。
-
Iteratordocumentation 中列出的任何内容都无济于事。我查看了itertools,它似乎也无济于事。 - 使用
while循环和索引,而不是使用利用对外部向量的引用的迭代器。这没关系,但不允许我使用迭代器和适配器。我只想摆脱这个外循环并使用my_vec.foreach(...)。
是否有任何习语或任何库可以让我很好地做到这一点 不安全的函数只要不向我公开指针就可以。
【问题讨论】:
-
some_index是常量吗?还是可以预测? -
只看每次迭代时
inner的具体内容。
标签: iterator rust borrow-checker