由于使用关联类型,在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
}
我不明白为什么迭代和直接实例化有什么区别。
iter()
而不是into_iter()
,它会起作用。 - Peter Hall