【发布时间】:2023-03-25 19:26:02
【问题描述】:
当有一个 trait 对象传递给函数时如何处理生命周期?
struct Planet<T> {
i: T,
}
trait Spinner<T> {
fn spin(&self, value: T);
}
impl<T> Spinner<T> for Planet<T> {
fn spin(&self, value: T) {}
}
// foo2 fails: Due to lifetime of local variable being less than 'a
fn foo2<'a>(t: &'a Spinner<&'a i32>) {
let x: i32 = 10;
t.spin(&x);
}
// foo1 passes: But here also the lifetime of local variable is less than 'a?
fn foo1<'a>(t: &'a Planet<&'a i32>) {
let x: i32 = 10;
t.spin(&x);
}
此代码导致此错误:
error[E0597]: `x` does not live long enough
--> src/main.rs:16:17
|
16 | t.spin(&x);
| ^ borrowed value does not live long enough
17 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:5...
--> src/main.rs:14:5
|
14 | fn foo2<'a>(t: &'a Spinner<&'a i32>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo1 的函数签名与foo2 几乎相同。一个接收对 struct 的引用,另一个接收 trait 对象。
我读到这是 Higher Ranked Trait Bounds 的用武之地。将 foo2 修改为 foo2(t: &for<'a> Spinner<&'a i32>) 会编译代码,但我不明白为什么。
为什么'a 不会缩小为x?
引用the Nomicon:
我们到底应该如何表达
F的特征绑定上的生命周期?我们需要在那里提供一些生命周期,但是我们关心的生命周期在我们进入调用体之前无法命名!此外,这不是固定的生命周期。call适用于任何生命周期&self在这一点上恰好有。
能否详细说明一下?
【问题讨论】: