我从这个 Rust 代码中得到了一个意外的错误:
struct Container<'a> {
x: &'a i32,
}
trait Reply {}
impl Reply for i32 {}
fn json<T>(_val: &T) -> impl Reply {
3
}
fn f() -> impl Reply {
let i = 123;
let a = Container { x: &i };
json(&a)
}
错误是:
error[E0597]: `i` does not live long enough
--> src/lib.rs:14:28
|
12 | fn f() -> impl Reply {
| ---------- opaque type requires that `i` is borrowed for `'static`
13 | let i = 123;
14 | let a = Container { x: &i };
| ^^ borrowed value does not live long enough
15 | json(&a)
16 | }
| - `i` dropped here while still borrowed
为什么?
如果我将
json()
的声明更改为以下任一版本,代码将编译:
fn json(val: &Container) -> impl Reply
fn json<T>(val: &T) -> i32
只有当同时存在类型参数和返回的特征对象时,编译器才会拒绝该代码。
这是我们遇到的实际问题的减少
warp::reply::json()
,但我更愿意总体上理解它。
当函数的参数和返回类型是泛型时,Rust 编译器假定返回类型可能会借用参数。这就是为什么它假设
f()
返回引用局部变量 i
的值。
我不完全确定,但我认为这是理想的,因为有人可以为可能出现问题的类型实现
Reply
。
编辑:由于错误,这不起作用。已经在 GitHub 上报道过。
四年后,我们有了深入的答案:Rust 问题分析#42940
我认为关键部分是这样的:
test
返回的值不引用当前函数拥有的任何数据。错误消息是错误的。但是,
test
does返回的 type 引用仅在当前函数内有效的生命周期。这才是真正的问题。