我应该如何描述泛型类型的生命周期关系?
How should I describe generic types lifetime relationship?
假设有一个典型的 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
有 deref(&self) -> &Self::Target
方法,这个逻辑不适用于 Deref<Target=U>
的情况,这意味着对于任何生命周期 T: 'a
然后 U: 'a
.
我如何告诉编译器后一种情况实际上是安全的?
问题是你把T
和U
都变成了独立的类型参数,但实际上U
总是唯一确定的通过 T
.
使用 T
的 Deref::Target
类型是您 真正 的意思,并且还使类型检查器更容易推断生命周期。
impl<T> MyIterator for T
where
T: Deref,
{
type Item<'a> = &'a <T as Deref>::Target
where
Self: 'a;
fn next(&mut self) -> Self::Item<'_> {
<T as Deref>::deref(self)
}
}
假设有一个典型的 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
有 deref(&self) -> &Self::Target
方法,这个逻辑不适用于 Deref<Target=U>
的情况,这意味着对于任何生命周期 T: 'a
然后 U: 'a
.
我如何告诉编译器后一种情况实际上是安全的?
问题是你把T
和U
都变成了独立的类型参数,但实际上U
总是唯一确定的通过 T
.
使用 T
的 Deref::Target
类型是您 真正 的意思,并且还使类型检查器更容易推断生命周期。
impl<T> MyIterator for T
where
T: Deref,
{
type Item<'a> = &'a <T as Deref>::Target
where
Self: 'a;
fn next(&mut self) -> Self::Item<'_> {
<T as Deref>::deref(self)
}
}