blob: 71ffb83f5943a08bb26bc2d56982305ba956365c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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)) }),
)]
}
...
```
|