为什么参数s寿命不足

时间:2019-01-28 06:44:13

标签: rust

代码:

use std::fmt::Debug;

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

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

fn foo(b: Box<DoSomthing<&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<DoSomthing<&i32>>) {
   |        - has type `std::boxed::Box<(dyn DoSomthing<&'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

我认为这个&s只是在foo中使用,foo方法结束了,不再借用了吗?但是事实并非如此。谁还在借钱?如何解决这个问题呢?非常感谢你!

1 个答案:

答案 0 :(得分:1)

只要在Rust中有参考,就存在一生。在大多数情况下,编译器可以推断出它,因此您不必写下来,但它仍然存在。当您遇到令人困惑的生命周期错误时,它有助于尝试找出这些隐式生命周期是什么。

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

这等效于

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

换句话说,传递给do_sth的引用的生存期实际上是“ foo的调用者想要的任何东西”。这个函数签名使我可以编写以下主要代码:

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

如果您为此参数扩展DoSomthing特性,则会得到以下功能:

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

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

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

至于您应该写些什么,我认为总体上来说这不是真正值得回答的问题。无法以这样的方式写do_sth签名:“传递给该函数的所有引用都可能是瞬态的”。您必须查看您的实际代码,并想出一种更好的编写方法。