【问题标题】:Rust: how to bound the lifetime of Iterator::next()?Rust:如何限制 Iterator::next() 的生命周期?
【发布时间】:2021-02-23 06:33:49
【问题描述】:

以下代码无法编译:

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!");
}

它抱怨:

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`

next 更改为next(&amp;'a mut self) 不起作用(签名不匹配),将self.contents.get_mut() 更改为self.contents.get_mut::&lt;'a&gt;() 也不起作用。

解决这个问题的正确方法是什么?

【问题讨论】:

标签: rust iterator lifetime


【解决方案1】:

我看到了两个问题。首先是您的iter_mut 函数尝试返回对self.things 的可变和不可变引用。

通过简化它更容易看出为什么借用检查器不允许这样做:

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);
}

第二个问题是您试图返回比传递给next 函数更长的引用。

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
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-03
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 2014-09-10
    • 2020-11-29
    相关资源
    最近更新 更多