Rust 为什么作为参数传递的trait对象的生存期需要更高的trait界限,而struct不需要';T

Rust 为什么作为参数传递的trait对象的生存期需要更高的trait界限,而struct不需要';T,rust,lifetime,Rust,Lifetime,当有一个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 o

当有一个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);
}
struct Planet{
i:T,
}
特质纺纱机{
fn旋转(和自身,值:T);
}
行星旋转器{
fn自旋(&self,值:T){}
}
//foo2失败:由于局部变量的生存期小于'a
fn foo2 src/main.rs:14:5
|

14 | fn foo2微调器简而言之:
foo1
编译,因为大多数类型在其泛型参数上是可变的,编译器仍然可以为
t
选择
微调器
foo2
不会编译,因为特征在其泛型参数上是不变的,并且
微调器
impl已经修复


一些解释 让我们看一下
foo
的第三个版本:

fn foo3<'a>(t: &'a Planet<&'a i32>) {
    let x: i32 = 10;
    Spinner::<&'a i32>::spin(t, &x);
}
fn foo4<'a, S: Spinner<&'a i32>>(t: &'a S) {
    let x: i32 = 10;
    t.spin(&x);
}
这里,调用方也给出了生存期
'a
,不能由
foo1
选择。但是,
foo1
可以选择要使用的
微调器的impl!请注意,
impl Spinner for Planet
基本上定义了无限多个特定实现(每个
T
一个)。因此编译器也知道
Planet
(其中
'x
是函数中
x
的特定生存期)

现在,编译器只需要弄清楚它是否可以将
星球
。是的,它可以,因为因此如果
'a
'x
的一个子类型(它是)。因此,编译器只需将
t
转换为
Planet
impl即可使用


太棒了!但是现在来看主要部分:那么为什么
foo2
不编译呢?
再次提醒一下:

fn foo1<'a>(t: &'a Planet<&'a i32>) {
    let x: i32 = 10;
    t.spin(&x);
}
fn foo2<'a>(t: &'a Spinner<&'a i32>) {
    let x: i32 = 10;
    t.spin(&x);
}
在本例中,
foo2
'a
'static
。实际上,
Star
仅为
静态
引用
i32
实现
微调器


顺便说一下:这不是特定于trait对象的让我们看看第四个版本的
foo

fn foo3<'a>(t: &'a Planet<&'a i32>) {
    let x: i32 = 10;
    Spinner::<&'a i32>::spin(t, &x);
}
fn foo4<'a, S: Spinner<&'a i32>>(t: &'a S) {
    let x: i32 = 10;
    t.spin(&x);
}

fn foo4>(t:&S)

从上面的解释中可以清楚地看到,这是可行的,因为
微调器的具体impl不再是固定的!相反,我们又有无限多个impl可供选择(每个
'a
一个impl)。因此,我们可以选择impl,其中
'a=='x

谢谢!这很有见地。
fn foo4<S: for<'a> Spinner<&'a i32>>(t: &S)