使用具有生命周期参数的关联类型特征的生命周期错误
Lifetime error using associated type of trait with lifetime parameter
由于使用关联类型,我遇到了 Rust 1.14 的生命周期错误,以下两个类似的程序证明了这一点,第一个编译没有错误,第二个有生命周期错误。
程序 #1 — 编译无误
trait Trait<'a> {
type T;
}
struct Impl;
impl<'a> Trait<'a> for Impl {
type T = std::marker::PhantomData<&'a ()>;
}
struct Alpha<'a, T: Trait<'a>> {
_dummy: std::marker::PhantomData<(&'a (), T)>,
}
fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {}
fn main() {
for x in Vec::<Alpha<Impl>>::new().into_iter() {
use_alpha(&x); // <-- ok
}
}
程序 #2 — 存在生命周期错误
trait Trait<'a> {
type T;
}
struct Impl;
impl<'a> Trait<'a> for Impl {
type T = std::marker::PhantomData<&'a ()>;
}
struct Alpha<'a, T: Trait<'a>> {
_dummy: std::marker::PhantomData<(&'a (), T::T)>,
}
fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {}
fn main() {
for x in Vec::<Alpha<Impl>>::new().into_iter() {
use_alpha(&x); // <-- !error!
}
}
这是第二个程序的编译时错误:
error: `x` does not live long enough
--> src/main.rs:20:5
|
19 | use_alpha(&x); // <-- !error!
| - borrow occurs here
20 | }
| ^ `x` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
这是两个程序的区别:
#[derive(Clone)]
struct Alpha<'a, T: Trait<'a>> {
- _dummy: std::marker::PhantomData<(&'a (), T)>,
+ _dummy: std::marker::PhantomData<(&'a (), T::T)>,
}
唯一的区别是,通过将第一个程序更改为使用关联类型而不是 struct
定义中的类型参数,会发生生命周期错误。我不知道为什么会这样。据我所知,关联类型不应引起任何额外的生命周期限制——它只是 'a
,但显然 Rust 编译器不同意。
如果我用简单的实例化替换第二个程序的 main
函数中的迭代,那么生命周期错误就会消失。即:
fn main() {
let x = Alpha::<Impl> { _dummy: std::marker::PhantomData };
use_alpha(&x); // <-- ok in both programs
}
我不明白为什么迭代与直接实例化有什么不同。
在 use_alpha
中,您对 Alpha
的引用及其生命周期参数使用了相同的生命周期。它的生命周期参数就变成了 Impl
的 Trait::T
的生命周期。该注释给出了有关值被删除顺序的提示:Impl::T
在 Impl
之前被删除,因为它是 Impl
定义的一部分,但这意味着 [=12= 的某些部分] 在它还在的时候已经被丢弃了。
您可以通过在 use_alpha
:
中使用两个生命周期参数来解决这个问题
fn use_alpha<'a, 'b>(_: &'a Alpha<'b, Impl>) {}
这将允许编译器为每种类型推断出不同的生命周期。
由于使用关联类型,我遇到了 Rust 1.14 的生命周期错误,以下两个类似的程序证明了这一点,第一个编译没有错误,第二个有生命周期错误。
程序 #1 — 编译无误
trait Trait<'a> {
type T;
}
struct Impl;
impl<'a> Trait<'a> for Impl {
type T = std::marker::PhantomData<&'a ()>;
}
struct Alpha<'a, T: Trait<'a>> {
_dummy: std::marker::PhantomData<(&'a (), T)>,
}
fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {}
fn main() {
for x in Vec::<Alpha<Impl>>::new().into_iter() {
use_alpha(&x); // <-- ok
}
}
程序 #2 — 存在生命周期错误
trait Trait<'a> {
type T;
}
struct Impl;
impl<'a> Trait<'a> for Impl {
type T = std::marker::PhantomData<&'a ()>;
}
struct Alpha<'a, T: Trait<'a>> {
_dummy: std::marker::PhantomData<(&'a (), T::T)>,
}
fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {}
fn main() {
for x in Vec::<Alpha<Impl>>::new().into_iter() {
use_alpha(&x); // <-- !error!
}
}
这是第二个程序的编译时错误:
error: `x` does not live long enough
--> src/main.rs:20:5
|
19 | use_alpha(&x); // <-- !error!
| - borrow occurs here
20 | }
| ^ `x` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
这是两个程序的区别:
#[derive(Clone)]
struct Alpha<'a, T: Trait<'a>> {
- _dummy: std::marker::PhantomData<(&'a (), T)>,
+ _dummy: std::marker::PhantomData<(&'a (), T::T)>,
}
唯一的区别是,通过将第一个程序更改为使用关联类型而不是 struct
定义中的类型参数,会发生生命周期错误。我不知道为什么会这样。据我所知,关联类型不应引起任何额外的生命周期限制——它只是 'a
,但显然 Rust 编译器不同意。
如果我用简单的实例化替换第二个程序的 main
函数中的迭代,那么生命周期错误就会消失。即:
fn main() {
let x = Alpha::<Impl> { _dummy: std::marker::PhantomData };
use_alpha(&x); // <-- ok in both programs
}
我不明白为什么迭代与直接实例化有什么不同。
在 use_alpha
中,您对 Alpha
的引用及其生命周期参数使用了相同的生命周期。它的生命周期参数就变成了 Impl
的 Trait::T
的生命周期。该注释给出了有关值被删除顺序的提示:Impl::T
在 Impl
之前被删除,因为它是 Impl
定义的一部分,但这意味着 [=12= 的某些部分] 在它还在的时候已经被丢弃了。
您可以通过在 use_alpha
:
fn use_alpha<'a, 'b>(_: &'a Alpha<'b, Impl>) {}
这将允许编译器为每种类型推断出不同的生命周期。