【问题标题】:"cannot infer an appropriate lifetime for pattern due to conflicting requirements" in `ref mut` pattern`ref mut` 模式中的“由于要求冲突,无法推断模式的适当生命周期”
【发布时间】:2017-07-12 19:56:33
【问题描述】:
struct RefWrap<'a> {
    wrap: &'a mut Option<String>,
}

impl<'a> RefWrap<'a> {
    fn unwrap(&mut self) -> &'a mut String {
        match *self.wrap {
            Some(ref mut s) => s,
            None => panic!(),
        }
    }
}

(Playground)

据我了解,这段代码是正确的(返回的引用确实有生命周期'a。但是Rust会产生以下错误:

error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements
 --> <anon>:8:18
  |
8 |             Some(ref mut s) => s,
  |                  ^^^^^^^^^

Using immutable references,它可以正常工作。

one similar question,但我很确定它在这种情况下没有帮助。

【问题讨论】:

    标签: rust lifetime


    【解决方案1】:

    看起来冲突是返回值:

    • 必须至少在生命周期内有效'a
    • 不得超过&amp;mut self,这只是函数调用的生命周期。

    如果允许,它会让你调用它两次并获得两个&amp;'a mut 对相同String 内容的引用:

    let mut w = RefWrap { wrap: &mut s };
    let ref1 = w.unwrap();
    let ref2 = w.unwrap();  // two mutable references!
    

    原因是 Rust 关于是否借用某物的推理方式是将生命周期捆绑在一起 - 但在这里你明确地说返回值的生命周期与 &amp;mut self 无关,这意味着它不会延长借用 -然后你可以通过另一个电话再次借用。

    这里的解决方案是在不冒第二个&amp;mut 引用与它重叠的风险的情况下获得原始引用生命周期,是按值(移动)获取self,以便它不能再次使用。编译器对此很满意:

    impl<'a> RefWrap<'a> {
        fn unwrap(self) -> &'a mut String {
            match *self.wrap {
                Some(ref mut s) => s,
                None => panic!(),
            }
        }
    }
    

    (Playground)

    【讨论】:

    • "它会让你调用两次并获得两个 &amp;'a mut 引用" -> 我不这么认为。例如,查看this code。我使用transmute() 使该方法起作用,但我仍然无法创建两个可变引用。另外:我特别希望返回的引用具有“更长”的生命周期,即'a
    • 是的,你可以:play.rust-lang.org/…
    猜你喜欢
    • 2022-01-06
    • 2020-01-29
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 2017-05-07
    • 2021-08-02
    • 2021-11-02
    • 1970-01-01
    相关资源
    最近更新 更多