diff options
Diffstat (limited to 'source/_posts/Rust-闭包-lifetime-may-not-live-long-enough-问题.md')
| -rw-r--r-- | source/_posts/Rust-闭包-lifetime-may-not-live-long-enough-问题.md | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/source/_posts/Rust-闭包-lifetime-may-not-live-long-enough-问题.md b/source/_posts/Rust-闭包-lifetime-may-not-live-long-enough-问题.md new file mode 100644 index 00000000..71ffb83f --- /dev/null +++ b/source/_posts/Rust-闭包-lifetime-may-not-live-long-enough-问题.md @@ -0,0 +1,62 @@ +--- +title: Rust 闭包 lifetime may not live long enough 问题 +date: 2023-05-24 18:04:23 +tags: [Technique] +--- + +代码: +```rust +... + fn handlers(self) -> crate::server::request::Handlers { + vec![( + "/tree", + routing::get(move || async { + ( + StatusCode::OK, + Json(json!(self.clone().tree(self.clone().root))), + ) + }), + )] + } +... +``` + +编译错误: +```text +error: lifetime may not live long enough + --> src/storage/filesystem/mod.rs:45:34 + | +45 | routing::get(move || async { + | __________________________-------_^ + | | | | + | | | return type of closure `{async block@src/storage/filesystem/mod.rs:45:34: 50:14}` contains a lifetime `'2` + | | lifetime `'1` represents this closure's body +46 | | ( +47 | | StatusCode::OK, +48 | | Json(json!(self.clone().tree(self.clone().root))), +49 | | ) +50 | | }), + | |_____________^ returning this value requires that `'1` must outlive `'2` + | + = note: closure implements `Fn`, so references to captured variables can't escape the closure +``` + +这是因为 `handlers` 里面的闭包捕获了一个引用,并且尝试返回一个包含该引用的值导致的。 + +细说就是:闭包内部使用了 `self.clone()` 来获取一个新的实例,然后在异步块中返回一个 JSON 对象,这个 JSON 对象依赖于 `self.tree()` 的结果。因为闭包捕获了 `self` 的引用,所以它必须保证 `self` 在闭包执行完毕后仍然有效。 + +解决这个问题的思路是:确保闭包中的所有引用都在闭包执行完毕之前就不再被使用。 +就是说,要将闭包的作用域限制在一个更短的生命周期内,或者使用其他方式来避免闭包捕获长期存在的引用: + +```rust + +... + fn handlers(self) -> crate::server::request::Handlers { + let tree = json!(self.clone().tree(self.clone().root)); + vec![( + "/tree", + routing::get(move || async { (StatusCode::OK, Json(tree)) }), + )] + } +... +```
\ No newline at end of file |
