简体   繁体   English

Rust:如何限制 Iterator::next() 的生命周期?

[英]Rust: how to bound the lifetime of Iterator::next()?

The following code doesn't compile:以下代码无法编译:

struct Things {
    things: Vec<usize>
}

struct ThingsIterMut<'a> {
    contents: &'a mut Vec<usize>,
    indices: std::slice::Iter<'a, usize>
}

impl<'a> Iterator for ThingsIterMut<'a> {
    type Item = &'a mut usize;

    fn next(&mut self) -> Option<Self::Item> {
        match self.indices.next() {
            None => None,
            Some(i) => self.contents.get_mut(*i)
        }
    }

}

impl Things {
    pub fn iter_mut<'a>(&'a mut self) -> ThingsIterMut<'a> {
        ThingsIterMut {
            contents: &mut self.things,
            indices: self.things.iter()
        }

    }
}

fn main() {
    println!("Hello, world!");
}

It complains:它抱怨:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/main.rs:16:24
   |
16 |             Some(i) => self.contents.get_mut(*i)
   |                        ^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 13:5...
  --> src/main.rs:13:5
   |
13 |     fn next(&mut self) -> Option<Self::Item> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:16:24
   |
16 |             Some(i) => self.contents.get_mut(*i)
   |                        ^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 10:6...
  --> src/main.rs:10:6
   |
10 | impl<'a> Iterator for ThingsIterMut<'a> {
   |      ^^
note: ...so that the types are compatible
  --> src/main.rs:13:46
   |
13 |       fn next(&mut self) -> Option<Self::Item> {
   |  ______________________________________________^
14 | |         match self.indices.next() {
15 | |             None => None,
16 | |             Some(i) => self.contents.get_mut(*i)
17 | |         }
18 | |     }
   | |_____^
   = note: expected `std::iter::Iterator`
              found `std::iter::Iterator`

Changing next to next(&'a mut self) dose not work (signature mismatch), neither does change self.contents.get_mut() to self.contents.get_mut::<'a>() .更改next next(&'a mut self)不起作用(签名不匹配),也不self.contents.get_mut()更改为self.contents.get_mut::<'a>()

What's the correct way to address this issue?解决这个问题的正确方法是什么?

I see two problems.我看到两个问题。 The first is that your iter_mut function tries to return both a mutable and an immutable reference to self.things .首先是您的iter_mut function 尝试返回对self.things的可变和不可变引用。

It is easier to see why the borrow checker doesn't allow this by simplifying it:通过简化它更容易看出为什么借用检查器不允许这样做:

fn main() {
    let mut things = vec![1, 2, 3];
    let contents = &mut things;
    let indices = things.iter(); // borrows self_things immutably
    let things_iter_mut = (contents, indices);
}

The second problem that you are trying to return a longer reference than you pass into the next function.第二个问题是您试图返回比传递给next function 的引用更长的引用。

struct Things<'things> {
    contents: &'things mut Vec<usize>,
}

impl<'things> Things<'things> {
    // This won't compile! The 'borrow lifetime is implied.
    // But here you can see that the borrow might be shorter than
    // what we are returning.
    fn next(&'borrow mut self) -> &'things mut Vec<usize> {
        self.contents
    }

    // This will compile. Because the returned reference lives
    // just as long as the argument.
    fn next(&'things mut self) -> &'things mut Vec<usize> {
        self.contents
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM