【问题标题】:Why does my reference not live long enough?为什么我的参考寿命不够长?
【发布时间】:2020-06-26 05:38:31
【问题描述】:

代码:

use std::fmt::Debug;

trait DoSomething<T> {
    fn do_sth(&self, value: T);
}

impl<T: Debug> DoSomething<T> for &usize {
    fn do_sth(&self, value: T) {
        println!("{:?}", value);
    }
}

fn foo(b: Box<DoSomething<&i32>>) {
    let s = 123;
    b.do_sth(&s);
}

fn main() {
    foo(Box::new(&3));
}

编译器错误信息是:

error[E0597]: `s` does not live long enough
  --> src/main.rs:15:14
   |
13 | fn foo(b: Box<DoSomething<&i32>>) {
   |        - has type `std::boxed::Box<(dyn DoSomething<&'1 i32> + '_)>`
14 |     let s = 123;
15 |     b.do_sth(&s);
   |     ---------^^-
   |     |        |
   |     |        borrowed value does not live long enough
   |     argument requires that `s` is borrowed for `'1`
16 | }
   | - `s` dropped here while still borrowed

我认为这个&amp;s只是在foo中使用,foo方法结束并且不再借用了?但事实并非如此。谁还在借?如何解决这个问题?

【问题讨论】:

    标签: rust


    【解决方案1】:

    只要有 Rust 中的引用,就有生命周期。在大多数情况下,编译器可以推断它,因此您不必将其写下来,但它仍然存在。当您遇到令人困惑的生命周期错误时,尝试弄清楚这些隐式生命周期是什么会有所帮助。

    fn foo(b: Box<DoSomething<&i32>>) {
        let s = 123;
        b.do_sth(&s);
    }
    

    这相当于

    fn foo<'y>(b: Box<DoSomething<&'y i32>>) {
        let s = 123;
        b.do_sth(&s);
    }
    

    换句话说,传递给do_sth 的引用的生命周期实际上是“foo 的调用者想要的任何东西”。这个函数签名允许我写这个 main:

    fn main() {
        let b : Box<DoSomething<&'static i32>> = Box::new(&3);
        foo(b);
    }
    

    如果你为这个参数扩展DoSomething trait,你最终会得到这个函数:

    fn do_sth(&self, value: &'static i32) {
        println!("{:?}", value);
    }
    

    foo 正在尝试使用对局部变量的引用进行调用。

    我希望这能解释为什么您的代码不起作用。

    至于你应该写什么,我认为这不是一般的回答。没有办法以“传递给此函数的所有引用可能是暂时的”的方式编写do_sth 签名。您必须查看您的真实代码并想出更好的编写方法。

    【讨论】:

    • 谢谢,我明白编译器为什么报错了
    • 为什么是'static?在这种情况下,终身省略不会导致fn do_sth&lt;'a&gt;(&amp;'a self, &amp;'a i32)(由于self)吗?
    • @Cerberus:不同的参数得到不同的生命周期;您正在考虑self 和返回引用在某些情况下共享相同的生命周期这一事实。
    • @Cerberus 'static 是您可以在本身未参数化的函数中命名的唯一生命周期。因此,这是我在示例中必须使用的。
    • @MatthieuM。谢谢,看来我弄错了省略规则。
    猜你喜欢
    • 2017-03-09
    • 1970-01-01
    • 2016-01-22
    • 2018-12-20
    • 2016-03-31
    • 2019-05-04
    • 2015-05-26
    • 1970-01-01
    • 2020-12-17
    相关资源
    最近更新 更多