迭代器的通用生命周期参数逐渐进入结构类型
Generic lifetime parameter of the iterator creeping into the struct type
我正在尝试创建一个数据结构(我们称之为 Outer
)来包装另一个数据结构(我们称之为 Inner
)。但是,我不想为 Inner
修复一个实现,而是想使用一个特征,这样我就可以轻松地交换这个底层数据结构的实现。
简化版看起来有点像这样:
pub struct Outer<K, V, I>
where
I: Inner<K, V>
{
inner: I,
// some phantom data fields
}
pub trait Inner<K, V>
{
...
}
现在,我想给 Outer
添加一个迭代器,它也应该包装一个由内部数据结构提供的迭代器,问题就来了。
在 Inner
特征中,我不能写:
fn iter(&self) -> impl Iterator<Item = (&'_ K, &'_ V)>;
as impl Trait
语法在这里是不允许的,我也不能引入关联类型,如:
type Iterator<'a>: Iterator<Item = (&'a K, &'a V)>;
因为 generic associated types 还没有。
到目前为止我想到的是为迭代器设置一个单独的特征:
pub trait InnerIterator<'a, K: 'a, V: 'a>: Iterator<Item = (&'a K, &'a V)> {
type Inner: Inner<K, V>;
fn new(inner: &'a Self::Inner) -> Self;
}
然后Outer
接收到一个新的泛型类型参数InnerIt
:
pub struct Outer<K, V, I, InnerIt>
where
I: Inner<K, V>
{
inner: I,
// some phantom data fields
}
impl<K, V, I, InnerIt> Outer<K, V, I, InnerIt> {
pub fn iter<'a>(&'a self) -> InnerIt
where
I: Inner<K, V>,
InnerIt: InnerIterator<'a, K, V, Inner = I>,
K: 'a,
V: 'a,
{
InnerIt::new(&self.inner)
}
}
现在,当我想选择一些特定的 Inner
实现时,我有类似的东西:
pub type SomeOuter<'a, K, V> = Outer<K, V, SomeInner<K, V>, SomeInnerIterator<'a, K, V>>;
这里生命周期参数 'a
成为我的类型定义的一部分。
除了我必须添加至少两个参数以启用 iter_mut
和 into_iter
的问题之外,我的问题是拥有这个 'a
的后果是什么那里的参数,当使用这种类型时它会继续进一步传播吗?这种类型的用户会对这个生命周期参数感到惊讶吗?有没有一种方法可以在不引入通用迭代器类型及其 Outer
的生命周期的情况下实现迭代器?
would it continue to propagate further when using this type
任何想要嵌入您的类型的类型都需要有生命周期参数。
然而,有些地方生命周期省略将接管(例如在函数参数中):
struct Struct1<'a>(std::marker::PhantomData<&'a ()>);
struct Struct2<'a>(Struct1<'a>); // lifetime propagates to Struct2
fn func(_: Struct1){
println!("lifetime not needed. It is 'elided'");
}
would the user of this type be surprised by this lifetime parameter
他们不应该。在铁锈中,生命无处不在。例如,迭代切片是使用 struct with a lifetime parameter.
完成的
is there a way to implement iterators without introducing generic iterator types and their lifetimes for Outer?
你有生命周期参数的原因是你有一个 return 引用的迭代器。如果您的迭代器 return 是一个直接对象,则不需要生命周期。例如,如果您将向量转换为迭代器(因此 return 包含向量中的所有元素)it won't need a lifetime parameter
我正在尝试创建一个数据结构(我们称之为 Outer
)来包装另一个数据结构(我们称之为 Inner
)。但是,我不想为 Inner
修复一个实现,而是想使用一个特征,这样我就可以轻松地交换这个底层数据结构的实现。
简化版看起来有点像这样:
pub struct Outer<K, V, I>
where
I: Inner<K, V>
{
inner: I,
// some phantom data fields
}
pub trait Inner<K, V>
{
...
}
现在,我想给 Outer
添加一个迭代器,它也应该包装一个由内部数据结构提供的迭代器,问题就来了。
在 Inner
特征中,我不能写:
fn iter(&self) -> impl Iterator<Item = (&'_ K, &'_ V)>;
as impl Trait
语法在这里是不允许的,我也不能引入关联类型,如:
type Iterator<'a>: Iterator<Item = (&'a K, &'a V)>;
因为 generic associated types 还没有。
到目前为止我想到的是为迭代器设置一个单独的特征:
pub trait InnerIterator<'a, K: 'a, V: 'a>: Iterator<Item = (&'a K, &'a V)> {
type Inner: Inner<K, V>;
fn new(inner: &'a Self::Inner) -> Self;
}
然后Outer
接收到一个新的泛型类型参数InnerIt
:
pub struct Outer<K, V, I, InnerIt>
where
I: Inner<K, V>
{
inner: I,
// some phantom data fields
}
impl<K, V, I, InnerIt> Outer<K, V, I, InnerIt> {
pub fn iter<'a>(&'a self) -> InnerIt
where
I: Inner<K, V>,
InnerIt: InnerIterator<'a, K, V, Inner = I>,
K: 'a,
V: 'a,
{
InnerIt::new(&self.inner)
}
}
现在,当我想选择一些特定的 Inner
实现时,我有类似的东西:
pub type SomeOuter<'a, K, V> = Outer<K, V, SomeInner<K, V>, SomeInnerIterator<'a, K, V>>;
这里生命周期参数 'a
成为我的类型定义的一部分。
除了我必须添加至少两个参数以启用 iter_mut
和 into_iter
的问题之外,我的问题是拥有这个 'a
的后果是什么那里的参数,当使用这种类型时它会继续进一步传播吗?这种类型的用户会对这个生命周期参数感到惊讶吗?有没有一种方法可以在不引入通用迭代器类型及其 Outer
的生命周期的情况下实现迭代器?
would it continue to propagate further when using this type
任何想要嵌入您的类型的类型都需要有生命周期参数。 然而,有些地方生命周期省略将接管(例如在函数参数中):
struct Struct1<'a>(std::marker::PhantomData<&'a ()>);
struct Struct2<'a>(Struct1<'a>); // lifetime propagates to Struct2
fn func(_: Struct1){
println!("lifetime not needed. It is 'elided'");
}
would the user of this type be surprised by this lifetime parameter
他们不应该。在铁锈中,生命无处不在。例如,迭代切片是使用 struct with a lifetime parameter.
完成的is there a way to implement iterators without introducing generic iterator types and their lifetimes for Outer?
你有生命周期参数的原因是你有一个 return 引用的迭代器。如果您的迭代器 return 是一个直接对象,则不需要生命周期。例如,如果您将向量转换为迭代器(因此 return 包含向量中的所有元素)it won't need a lifetime parameter