Par*_*olu 4 closures lifetime rust
我写了以下内容来测试闭包:
fn main() {
let captured_val = "a captured value".to_string();
let closure_parameter = "a parameter value".to_string();
let mut ct = ClosureTest {
cls: |closure_parameter| &captured_val,
};
println!("{}", (ct.cls)(&closure_parameter));
}
struct ClosureTest<T>
where
T: FnMut(&str) -> &str,
{
cls: T,
}
Run Code Online (Sandbox Code Playgroud)
我收到以下编译错误:
fn main() {
let captured_val = "a captured value".to_string();
let closure_parameter = "a parameter value".to_string();
let mut ct = ClosureTest {
cls: |closure_parameter| &captured_val,
};
println!("{}", (ct.cls)(&closure_parameter));
}
struct ClosureTest<T>
where
T: FnMut(&str) -> &str,
{
cls: T,
}
Run Code Online (Sandbox Code Playgroud)
我向该结构添加了一个生命周期参数,它编译并运行良好:
struct ClosureTest<'a, T>
where
T: FnMut(&str) -> &'a str,
{
cls: T,
}
Run Code Online (Sandbox Code Playgroud)
两个变量 (captured_val和) 都在同一范围内,但如果没有我添加到 的closure_parameter生命周期参数,编译器似乎看不到它们具有相同的生命周期。这是因为 Rust 对闭包的生命周期推断吗?'aClosureTest<T>
我不明白收到的错误消息中的第一行:
error[E0373]: closure may outlive the current function, but it borrows `captured_val`, which is owned by the current function
--> src/main.rs:6:14
|
6 | cls: |closure_parameter| &captured_val,
| ^^^^^^^^^^^^^^^^^^^ ------------ `captured_val` is borrowed here
| |
| may outlive borrowed value `captured_val`
help: to force the closure to take ownership of `captured_val` (and any other referenced variables), use the `move` keyword
|
6 | cls: move |closure_parameter| &captured_val,
| ^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
闭包怎么可能比当前函数更长寿?闭包仅在当前函数中定义,因此我认为闭包将在当前函数末尾消失。
错误消息的真正含义是什么?为什么像我一样通过添加生命周期参数来解决它?
简短版本:添加显式生命周期注释可以保证没有它就ClosureTest不一定隐含什么。
假设你这样做了:
fn main() {
let closure_parameter = "a parameter value".to_string();
let returned_ct = do_something(v);
println!("{}", (returned_ct.cls)(&closure_parameter));
}
fn do_something() -> ClosureTest {
let captured_val = "a captured value".to_string();
let mut ct = ClosureTest {
cls: |param| &captured_val,
};
ct // !!!
}
struct ClosureTest<T>
where
T: FnMut(&str) -> &str,
{
cls: T,
}
Run Code Online (Sandbox Code Playgroud)
在标有 的行上!!!,请注意 已ct作为返回值移出函数。该对象现在“存在”于 中main,但它包含对结束时被删除的内容的引用do_something。ct.cls返回对 的引用,如果将其移出函数,captured_val该引用将不再存在。ct
通过修改ClosureTest以包含生命周期,您的意思是:
ClosureTest有obj一定的生命周期'astrlife返回的引用在定义为onobj.cls的整个生命周期内(如果不是更长的话)'aobjobj.cls的引用具有相同的范围ClosureTest。obj将与其闭包引用的对象同时删除,或更早删除。换句话说,anyClosureType<'a, T> where T: FnMut(&str) -> &'a str只能在对象T的返回引用存在时存在,并且必须在该对象被删除时删除。借用检查器不会对原始值感到恼火,因为ct和captured_value 具有不同的生命周期,这是因为它们可能有不同的生命周期 - 因此“可能比借用的价值”中的“可能captured_val”。当您在示例中添加生命周期参数时,借用检查器现在可以确认仅当captured_val生存期与 一样长时才应该编译ct,它确实这样做了(它们都在 末尾被删除main)。
| 归档时间: |
|
| 查看次数: |
4456 次 |
| 最近记录: |