假设有一个典型的GAT示例,引用迭代器:
#![feature(generic_associated_types)]
use std::ops::Deref;
trait MyIterator {
type Item<'a>
where
Self: 'a;
fn next(&mut self) -> Self::Item<'_>;
}
例如,我可以用Box<T>
美元实现这个功能.
// This is OK
impl<U> MyIterator for Box<U> {
type Item<'a> = &'a U
where
Self: 'a;
fn next(&mut self) -> Self::Item<'_> {
<Box<T> as Deref>::deref(self)
}
}
但当我用Deref
个特征来概括它时就不是了:
// error[E0309]: the parameter type `U` may not live long enough
impl<T, U> MyIterator for T
where
T: Deref<Target = U>,
{
type Item<'a> = &'a U
where
Self: 'a;
fn next(&mut self) -> Self::Item<'_> {
<T as Deref>::deref(self)
}
}
据我所知,在Box<T>
种情况下,编译器不知何故知道U
类型属于Box<U>
,因此U
的生命周期 肯定比Box<U>
长.如果是Box<U>: 'a
,那么编译器可以说是U: 'a
.
但这种逻辑在Deref<Target=U>
的情况下不起作用,即使Deref
有deref(&self) -> &Self::Target
个方法,这意味着在任何生命周期中,T: 'a
就是U: 'a
.
我如何告诉编译器后一种情况实际上是安全的?