我正在尝试创造一种特质来捕捉iter
函数于slice
也VecDeque
, BTreeMap
and HashMap
。我希望这个特征的实现者能够指定和实现他们自己的迭代器类型,但看起来这个迭代器类型必须有一个生命周期参数,并且不能作为关联类型给出。
更详细地说,这是我希望在 Rust 中可以实现的功能:
trait RefIterable<T>
where for<'a> (T: 'a) => (Self::Iter<'a>: Iterator<Item = &'a T>)
{
type Iter; // Has kind (lifetime -> type)
fn refs<'a>(&'a self) -> Self::Iter<'a>
}
如果这是可能的,实现可能如下所示
impl RefIterable<T> for Vec<T> {
type Iter<'a> = std::slice::Iter<'a, T>; // This is not valid Rust code.
fn refs<'a>(&'a self) -> std::slice::Iter<'a, T> {
self.as_slice().iter()
}
}
我对 Rust 还比较陌生,所以我想问是否已经有一种我不知道的方法可以做到这一点,或者对于这种情况是否有一个很好的解决方法。我想这种情况并不少见。
(Using Box<dyn 'a + Iterator<Item = &'a T>>
是我当前的解决方法,但这会阻止某些优化的发生。)
Edit:
EvilTak 的回答可能是我们现在能做的最好的事情。将所有可能的生命周期与条件结合起来的能力T: 'a
截至目前,Rust 似乎不支持将其转化为一种非参数化特征。
相反,将生命周期参数添加到特征中,这允许您在关联类型中使用它Iter
的绑定:
trait RefIterable<'a> {
type Item: 'a;
type Iter: Iterator<Item = &'a Self::Item>; // Has kind (lifetime -> type)
fn refs(&'a self) -> Self::Iter;
}
The Item: 'a
需要绑定让编译器知道引用(&'a Self::Item
)不会比类型(Self::Item
).
我已经修改了RefIterable
使其遵循Iterator
使用关联类型来指定迭代的项目类型的约定同样的原因 https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types作为后面的那个Iterator
关联类型的用法。
实现非常简单:
impl<'a, T: 'a> RefIterable<'a> for Vec<T> {
type Item = T;
type Iter = std::slice::Iter<'a, T>;
fn refs(&'a self) -> std::slice::Iter<'a, T> {
self.as_slice().iter()
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)