为什么这个&一生不同于& mut的寿命?

时间:2017-12-18 01:33:03

标签: data-structures iterator rust lifetime borrow-checker

我正在Rust中创建一个自定义数据结构并尝试为它实现迭代器。按照内置集合(LinkedListVec等)的示例,我创建了一个IntoIter结构,它遍历一个拥有的集合,Iter结构迭代借用的集合,以及迭代可变借用集合的IterMut结构。

我能够实现前两个迭代器但是我在使用IterMut取悦借用检查器时遇到了麻烦。我已将代码缩减到最低限度的repro,并用Vec<Option<T>>替换了我的自定义数据结构:

pub struct IterMut<'a, T: 'a> {
    list: &'a mut Vec<Option<T>>,
}

impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;

    fn next(&mut self) -> Option<&'a mut T> {
        let head_node = &mut self.list[0];
        // convert &mut Option<T> to Option<&mut T>
        head_node.as_mut()
    }
}

The example in the playground

无法使用

进行编译
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/main.rs:23:24
   |
23 |   let head_node = &mut self.list[0];
   |                        ^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 22:2...
  --> src/main.rs:22:2
   |
22 | /  fn next(&mut self) -> Option<&'a mut T> {
23 | |   let head_node = &mut self.list[0];
24 | |   // convert &mut Option<T> to Option<&mut T>
25 | |   head_node.as_mut()
26 | |  }
   | |__^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:23:24
   |
23 |   let head_node = &mut self.list[0];
   |                        ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 19:1...
  --> src/main.rs:19:1
   |
19 | / impl<'a, T> Iterator for IterMut<'a, T> {
20 | |  type Item = &'a mut T;
21 | |
22 | |  fn next(&mut self) -> Option<&'a mut T> {
...  |
26 | |  }
27 | | }
   | |_^
note: ...so that expression is assignable (expected std::option::Option<&'a mut T>, found std::option::Option<&mut T>)
  --> src/main.rs:25:3
   |
25 |   head_node.as_mut()
   |   ^^^^^^^^^^^^^^^^^^

真正让我感到困惑的是,这段代码几乎与我用于成功编译的Iter的代码相同:

pub struct Iter<'a, T: 'a> {
    list: &'a Vec<Option<T>>,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        let head_node = &self.list[0];
        // convert &Option<T> to Option<&T>
        head_node.as_ref()
    }
}

我知道&&mut是两个不同的东西,但我认为它们的生命期仍然会以同样的方式计算。我的第一个猜测是,as_ref()必须与as_mut()有所不同,但其实施的源代码似乎没有差异(as_refas_mut

什么是借用检查员抱怨?

0 个答案:

没有答案