gpt4 book ai didi

rust - 错误 "closure may outlive the current function"的真正含义是什么?

转载 作者:行者123 更新时间:2023-11-29 08:29:39 25 4
gpt4 key购买 nike

我写了以下代码来测试闭包:

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,
}

我得到以下编译错误:

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,
| ^^^^^^^^^^^^^^^^^^^^^^^^

我向该结构添加了一个生命周期参数,它编译并运行良好:

struct ClosureTest<'a, T>
where
T: FnMut(&str) -> &'a str,
{
cls: T,
}

两个变量(captured_valclosure_parameter)都在相同的范围内,但似乎编译器没有看到它们在没有生命周期参数 'a 的情况下具有相同的生命周期。我添加到 ClosureTest<T> .这是因为 Rust 对闭包的生命周期推断吗?

我不明白我收到的错误消息的第一行:

error[E0373]: closure may outlive the current function, but it borrows `captured_val`, which is owned by the current function

闭包如何比当前函数更长久?闭包只在当前函数中定义,所以我认为闭包将在当前函数结束时消失。

错误消息的真正含义是什么,为什么像我一样通过添加生命周期参数来解决?

最佳答案

简短版本:添加明确的生命周期注释可以保证关于 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,
}

在标记为!!! 的行上,请注意 ct作为返回值移出函数。该对象现在“存在于”main 中, 但它包含对在 do_something 时删除的内容的引用结束。 ct.cls正在返回对 captured_val引用 ,如果 ct 将不再存在被移出函数。

通过修改ClosureTest要包括生命周期,您是在说以下内容:

  • A ClosureTest对象 obj有一些生命'a
  • str obj.cls 返回的引用一生都在定义为'aobj ,如果不再
  • 因此,obj.cls 返回的任何引用与 ClosureTest 具有相同的范围返回它。 obj将与其闭包引用的对象同时被删除,或更早。换句话说,任何 ClosureType<'a, T> where T: FnMut(&str) -> &'a str对象只能存活 T的返回引用存在,并且必须在删除该对象时删除。

借用检查器不会对原始值感到恼火,因为 ctcaptured_value 不同的生命周期,这是因为它们可能有不同的生命周期 - 因此“可能”中的“可能”比借用的值(value)长寿 captured_val '.当您在示例中添加生命周期参数时,借用检查器现在可以确认它应该只在 captured_val 时编译。生命周期和ct一样长,它确实如此(它们都在 main 的末尾被丢弃)。

关于rust - 错误 "closure may outlive the current function"的真正含义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49164343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com