Vec的可变迭代器Vec

Vec的可变迭代器Vec

本文介绍了Vec的可变迭代器Vec(K,V)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为类型为Vec<Vec<(K, V)>>

迭代器代码:

pub struct IterMut<'a, K: 'a, V: 'a> {
    iter: &'a mut Vec<Vec<(K, V)>>,
    ix: usize,
    inner_ix: usize,
}

impl<'a, K, V> Iterator for IterMut<'a, K, V> {
    type Item = (&'a K, &'a mut V);

    #[inline]
    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {

        while self.iter.len() < self.ix {
            while self.iter[self.ix].len() < self.inner_ix {
                self.inner_ix += 1;
                let (ref k, ref mut v) = self.iter[self.ix][self.inner_ix];
                return Some((&k, &mut v));
            }

            self.ix += 1;
        }

        return None;
    }
}

我得到的错误是:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/main.rs:16:42
   |
16 |                 let (ref k, ref mut v) = self.iter[self.ix][self.inner_ix];
   |                                          ^^^^^^^^^^^^^^^^^^
   |
help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self) -> Option<(&'a K, &'a mut V)>
  --> src/main.rs:11:5
   |
11 |     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
   |     ^

显然我有终身问题,但是我不知道如何告诉编译器这应该工作.

Apparently I have lifetime problems, but I don't know how to tell the compiler that this should work.

这是应该如何实现可变迭代器,还是有更好的方法?

Is this how you should implement the mutable iterator or is there a better way?

推荐答案

在调试神秘的错误消息时,我发现更容易尝试并尽可能地隔离问题.

When debugging cryptic error messages, I've found it easier to try and isolate the issue as much as possible.

第一步是将表达式分解为其基本组成部分,让我们首先拆分索引步骤:

The first step is to break the expression into its essential constituents, let's start by splitting the indexing steps:

fn next(&mut self) -> Option<(&'a K, &'a mut V)> {

    while self.iter.len() < self.ix {
        while self.iter[self.ix].len() < self.inner_ix {
            self.inner_ix += 1;
            let outer: &'a mut Vec<_> = self.iter;
            let inner: &'a mut Vec<_> = &mut outer[self.ix];
            let (ref k, ref mut v) = inner[self.inner_ix];
            return Some((&k, &mut v));
        }

        self.ix += 1;
    }

    return None;
}

Index特征假定其输出的生存期与接收器的生存期相关,因此要获得'a生存期,我们需要接收器具有&'a生存期,并且它向上传播,从而导致上面的代码.

The Index trait assumes that the lifetime of its output is linked to that of its receiver, so to get a 'a lifetime we need the receiver to have a &'a lifetime, and it propagates upward, leading to the above code.

但是这里有一个问题:let outer: &'a mut Vec<_> = self.iter;不会编译,因为可变引用不是Copy.

However there's an issue here: let outer: &'a mut Vec<_> = self.iter; will not compile because mutable references are not Copy.

那么,如何从可变引用中获取可变引用(由于IndexMut获取了可变引用,这是必须的)?

So, how does one get a mutable reference from a mutable reference (which must be possible since IndexMut gets a mutable reference)?

一个使用重新借入:let outer: &'a mut Vec<_> = &mut *self.iter;.

还有,哦:

error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
  --> <anon>:16:45
   |
16 |                 let outer: &'a mut Vec<_> = &mut *self.iter;
   |                                             ^^^^^^^^^^^^^^^
   |

重新借出的引用对'a无效,仅对self的(未命名)生命周期有效!

The reborrowed reference is not valid for 'a, it's valid only for the (unnamed) lifetime of self!

为什么要生锈?为什么?

否则将是不安全的.

&mut T保证不会混叠,但是您的方法可以创建混叠引用(如果您忘记了推进索引的话):

&mut T is guaranteed NOT to be aliasing, however your method could create aliasing references (if you forgot to advance the index):

#[inline]
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
    let (ref k, ref mut v) = self.iter[self.ix][self.inner_ix];
    return Some((&k, &mut v));
}

即使您不这样做,也无法保证您没有rewind方法允许后退".

And even if you don't, there's not guarantee that you don't have a rewind method that would allow "stepping back".

TL; DR:您将要踩到一枚地雷,而是被引导到Stack Overflow;)

好的,但是您如何实现迭代器!.

当然,使用迭代器.正如Shepmaster(简短地)回答的那样,标准库中已经有类似的内容,其名称为 FlatMap .诀窍是使用现有的迭代器来获取详细信息!

Well, using iterators, of course. As Shepmaster (briefly) answers, there is the equivalent in the standard library already in the guise of FlatMap. The trick is to use existing iterators for the nitty-gritty details!

类似的东西:

use std::slice::IterMut;

pub struct MyIterMut<'a, K: 'a, V: 'a> {
    outer: IterMut<'a, Vec<(K, V)>>,
    inner: IterMut<'a, (K, V)>,
}

然后,您只要从inner中消费即可,只要它提供了物品,而当空时,您可以从outer中重新填充.

Then you consume from inner as long as it provides items, and when empty you refill it from outer.

impl<'a, K, V> MyIterMut<'a, K, V> {
    fn new(v: &'a mut Vec<Vec<(K, V)>>) -> MyIterMut<'a, K, V> {
        let mut outer = v.iter_mut();
        let inner = outer.next()
                         .map(|v| v.iter_mut())
                         .unwrap_or_else(|| (&mut []).iter_mut());
        MyIterMut { outer: outer, inner: inner }
    }
}

impl<'a, K, V> Iterator for MyIterMut<'a, K, V> {
    type Item = (&'a K, &'a mut V);

    #[inline]
    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
        loop {
            match self.inner.next() {
                Some(r) => return Some((&r.0, &mut r.1)),
                None => (),
            }

            match self.outer.next() {
                Some(v) => self.inner = v.iter_mut(),
                None => return None,
            }
        }
    }
}

一个快速的测试案例:

fn main() {
    let mut v = vec![
        vec![(1, "1"), (2, "2")],
        vec![],
        vec![(3, "3")]
    ];
    let iter = MyIterMut::new(&mut v);
    let c: Vec<_> = iter.collect();
    println!("{:?}", c);
}

打印:

[(1, "1"), (2, "2"), (3, "3")]

正如预期的那样,所以它并没有完全损坏,但是我希望我不必依靠&[]'static的把戏(即,std::slice::IterMut实现了Default).

as expected, so it's not completely broken, but I wish I did not have to rely on the &[] is 'static trick (ie, that std::slice::IterMut implemented Default).

这篇关于Vec的可变迭代器Vec(K,V)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 05:55