问题描述
对我来说很清楚,对向量进行迭代不应该让循环体随意改变向量.这样可以防止迭代器失效,而迭代器失效容易导致错误.
It is quite clear to me that iterating over a vector shouldn't let the loop body mutate the vector arbitrarily. This prevents iterator invalidation, which is prone to bugs.
但是,并非所有类型的突变都会导致迭代器失效.请参见以下示例:
However, not all kinds of mutation lead to iterator invalidation. See the following example:
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]
中特定元素的任何引用无效,但我们还是不会使用任何此类引用.
Such a mutation does not invalidate the iterator of my_vec
, however it is disallowed. It could invalidate any references to the specific elements in my_vec[some_index]
but we do not use any such references anyway.
我知道这些问题很常见,我不要求解释.我正在寻找一种重构方法,以便摆脱这种循环.在我的实际代码中,我有一个巨大的循环体,除非我很好地表达了这一点,否则我无法对其进行模块化.
I know that these questions are common, and I'm not asking for an explanation. I am looking for a way to refactor this so that I can get rid of this loop. In my actual code I have a huge loop body and I can't modularize it unless I express this bit nicely.
到目前为止我想到的是
- 用
Rc<RefCell<...>>
包装向量.我认为这在运行时仍然会失败,因为RefCell
将由迭代器借用,然后在循环主体尝试借用它时会失败. - 使用临时向量累积将来的推送,并在循环结束后推送它们.没关系,但是需要更多的分配,而不是立即进行分配.
- 不安全的代码,并且弄乱了指针.
-
Iterator
文档中列出的所有内容没有帮助.我签出了 itertools ,它似乎无济于事要么. - 使用
while
循环和索引,而不是使用对外部向量的引用的迭代器.可以,但是不允许我使用迭代器和适配器.我只想摆脱这个外部循环并使用my_vec.foreach(...)
.
- Wrapping the vector with
Rc<RefCell<...>>
. I think this would still fail at runtime, since theRefCell
would be borrowed by the iterator and then will fail when the loop body tries to borrow it. - Using a temporary vector to accumulate the future pushes, and push them after the loop ends. This is okay, but needs more allocations than pushing them on the fly.
- Unsafe code, and messing with pointers.
- Anything listed in the
Iterator
documentation does not help. I checked out itertools and it looks like it wouldn't help either. - Using a
while
loop and indexing instead of using an iterator making use of a reference to the outer vector. This is okay, but does not let me use iterators and adapters. I just want to get rid of this outer loop and usemy_vec.foreach(...)
.
有没有能让我做到这一点的惯用法或库,只要它们不向我公开指针,不安全的函数就可以了.
Are there any idioms or any libraries which would let me do this nicely Unsafe functions would be okay as long as they don't expose pointers to me.
推荐答案
无需更改my_vec
的类型,您只需通过建立索引和 split_at_mut
:
Without changing the type of my_vec
, you could simply use access by indexing and split_at_mut
:
for index in 0..my_vec.len() {
let (first, second) = my_vec.split_at_mut(index);
first[some_index].push(second[0]);
}
注意:请注意,second
中的索引已被index
关闭.
Note: beware, the indices in second
are off by index
.
这是安全,相对容易且非常灵活的.但是,它不适用于迭代器适配器.
This is safe, relatively easy, and very flexible. It does not, however, work with iterator adaptors.
这篇关于在迭代向量时,如何变异向量中的另一个项目,而不是向量本身?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!