【问题标题】:Infer an appropriate lifetime for methods including interior references推断包括内部引用在内的方法的适当生命周期
【发布时间】:2019-09-18 11:28:06
【问题描述】:

我正在学习 Rust 并面临编译问题。我简化了我的代码(所以它现在没有任何意义)在这里发布我的问题。

我有一个Parent 结构,其中填充了ChildWrapperVec<&Child>。但是编译器不会让我设置引用,因为创建的引用不一定会超过其内容。在我看来,在这里设置生命周期 (pub fn get<'a>(&'a self) -> &'a Child {) 应该让编译器放心, ref 的寿命会足够长……但是,不。

如果我从Parent 中取出ChildWrapper,我可以让它工作,但我仍然不明白我的代码有什么问题。

struct Child {
    e: bool,
}

impl Child {
    pub fn new() -> Child {
        Child { e: true }
    }
}

struct ChildWrapper {
    child: Child,
}

impl ChildWrapper {
    pub fn new() -> ChildWrapper {
        ChildWrapper { child: Child::new() }
    }

    pub fn get<'a>(&'a self) -> &'a Child {
        &self.child
    }
}

struct Parent<'a> {
    child_ref: Vec<&'a Child>,
    wrapper: ChildWrapper,
}

impl<'a> Parent<'a> {
    pub fn new() -> Parent<'a> {
        Parent {
            child_ref : Vec::new(),
            wrapper: ChildWrapper::new(),
        }
    }

    pub fn set_child_ref(&mut self) {
        self.child_ref.push(self.wrapper.get());
    }
}

fn main() {
    let mut parent = Parent::new();
    parent.set_child_ref();
}

这是我得到的错误:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/main.rs:41:36
   |
41 |         self.child_ref.push(self.wrapper.get());
   |                                          ^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 40:2...
  --> src/main.rs:40:2
   |
40 |       pub fn set_child_ref(&mut self) {
   |  _____^
41 | |         self.child_ref.push(self.wrapper.get());
42 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:41:23
   |
41 |         self.child_ref.push(self.wrapper.get());
   |                             ^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 32:6...
  --> src/main.rs:32:6
   |
32 | impl<'a> Parent<'a> {
   |      ^^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:41:23
   |
41 |         self.child_ref.push(self.wrapper.get());
   |                             ^^^^^^^^^^^^^^^^^^

我知道如何解决这个问题,这可能是设计不佳的标志(或者可能不是?),但我正在寻找解释并最终找到使用相同架构的解决方案...... 比如如何为self.wrapper.get()明确设置正确的生命周期?

谢谢!

【问题讨论】:

  • 实际上是自我响应......我已经与它斗争了几个小时,并在发布后立即找到了修复。也许它对其他人有用:pub fn set_child_ref(&amp;mut self) { => pub fn set_child_ref(&amp;'a mut self) { 我不知道为什么,但这一生必须是明确的。随时提供进一步的解释!
  • &amp;'a mut self,当'aSelf 的参数时,几乎总是一个错误。在这种情况下,它可以工作,但是您已经无法使用parent 执行任何操作else,因为它现在是永久(且唯一)借用的。此类问题的最佳解决方案是避免使用自引用结构。 Why can't I store a value and a reference to that value in the same struct?有进一步的解释和建议。

标签: reference rust lifetime


【解决方案1】:

在我看来,在这里设置生命周期 (pub fn get&lt;'a&gt;(&amp;'a self) -&gt; &amp;'a Child {) 应该可以让编译器放心 ref 将存在足够长的时间......但是,不。

您在此处提供的生命周期注释正是如果您省略它们,Rust 编译器会推断出的,所以这不会有任何区别。

正如所写,您的 set_child_ref 方法已经省略了生命周期,这意味着推断的生命周期是这样的:

impl<'a> Parent<'a> {
    pub fn set_child_ref<'b>(&'b mut self) {
        self.child_ref.push(self.wrapper.get());
    }
}

这行不通。 'b 的生命周期将由set_child_ref调用者 使用参数的方式决定。因此,对self 的引用可能比'a 的生命周期短。这会导致问题,因为您存储在 child_ref 中的对 ChildWrapper 的引用是从该(可能更短的)引用中借用的。

简单的解决方法是说self 的引用必须比'a 长,这是child_ref 向量中引用的生命周期:

impl<'a> Parent<'a> {
    pub fn set_child_ref(&'a mut self) {
        self.child_ref.push(self.wrapper.get());
    }
}

【讨论】:

    猜你喜欢
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 2020-08-27
    • 2021-03-23
    • 1970-01-01
    相关资源
    最近更新 更多