如何在 Rust 中为引用创建“Iterable”特征?

2024-05-15

我正在尝试创造一种特质来捕捉iter函数于sliceVecDeque, 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(使用前将#替换为@)

如何在 Rust 中为引用创建“Iterable”特征? 的相关文章

随机推荐