Rust 为什么作为参数传递的trait对象的生存期需要更高的trait界限,而struct不需要';T
当有一个trait对象传递给函数时,如何处理生命期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
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)