请考虑以下示例(游乐场):
struct Animal<'a> {
format: &'a dyn Fn() -> (),
}
impl <'a>Animal<'a> {
pub fn set_formatter(&mut self, _fmt: &'a dyn Fn() -> ()) -> () {} // Getting rid of 'a here satisfies the compiler
pub fn bark(&self) {}
}
fn main() {
let mut dog: Animal = Animal { format: &|| {()} };
let x = 0;
dog.set_formatter(&|| {
println!("{}", x); // Commenting this out gets rid of the error. Why?
});
dog.bark(); // Commenting this out gets rid of the error. Why?
}
这会产生以下编译错误:
Compiling playground v0.0.1 (/playground)
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:13:24
|
13 | dog.set_formatter(&|| {
| ________________________^
14 | | println!("{}", x); // Commenting this out gets rid of the error. Why?
15 | | });
| | ^ - temporary value is freed at the end of this statement
| |_____|
| creates a temporary which is freed while still in use
16 | dog.bark(); // Commenting this out gets rid of the error. Why?
| --- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
error: aborting due to previous error
For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
这种情况是有道理的,因为我传递给的闭包dog.set_formatter(...)
确实是一个临时的(我猜)当执行继续时被释放dog.bark();
。
我知道在实现中摆脱显式生命周期注释set_formatter
似乎满足编译器(注意'a
之前缺少的dyn
):
pub fn set_formatter(&mut self, _fmt: & dyn Fn() -> ()) -> () {}
但是,我不明白以下内容:
println!("{}", x);
当我在闭包内注释掉时,为什么问题会消失?我仍在传递一个我希望编译器抱怨的临时文件,但事实并非如此。- 当我在最后注释掉时,为什么问题会消失
dog.bark();
?同样,我仍在传递一个已释放的临时闭包,但现在编译器很高兴。为什么?