代码:
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方法结束了,不再借用了吗?但是事实并非如此。谁还在借钱?如何解决这个问题呢?非常感谢你!
答案 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
签名:“传递给该函数的所有引用都可能是瞬态的”。您必须查看您的实际代码,并想出一种更好的编写方法。