在迭代向量时,如何变异向量中的另一个项目,而不是向量本身? [英] How to mutate another item in a vector, but not the vector itself, while iterating over the vector?

查看:71
本文介绍了在迭代向量时,如何变异向量中的另一个项目,而不是向量本身?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对我来说很清楚,对向量进行迭代不应该让循环体随意改变向量.这样可以防止迭代器失效,而迭代器失效容易导致错误.

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.

到目前为止我想到的是

  1. Rc<RefCell<...>>包装向量.我认为这在运行时仍然会失败,因为RefCell将由迭代器借用,然后在循环主体尝试借用它时会失败.
  2. 使用临时向量累积将来的推送,并在循环结束后推送它们.没关系,但是需要更多的分配,而不是立即进行分配.
  3. 不安全的代码,并且弄乱了指针.
  4. Iterator文档中列出的所有内容没有帮助.我签出了 itertools ,它似乎无济于事要么.
  5. 使用while循环和索引,而不是使用对外部向量的引用的迭代器.可以,但是不允许我使用迭代器和适配器.我只想摆脱这个外部循环并使用my_vec.foreach(...).
  1. Wrapping the vector with Rc<RefCell<...>>. I think this would still fail at runtime, since the RefCell would be borrowed by the iterator and then will fail when the loop body tries to borrow it.
  2. 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.
  3. Unsafe code, and messing with pointers.
  4. Anything listed in the Iterator documentation does not help. I checked out itertools and it looks like it wouldn't help either.
  5. 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 use my_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的类型,您只需通过建立索引和

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.

这篇关于在迭代向量时,如何变异向量中的另一个项目,而不是向量本身?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆