我如何创建一个 trait/type 来统一迭代来自 Range 或 Vec 的一些整数集?

How can I create a trait/type to unify iterating over some set of integers from either a Range or a Vec?

我需要特征 XYZ 来定义一个允许迭代某些整数集的方法。这组整数由支持 VecRange<usize> 定义。但是,我 运行 陷入各种(生命周期或类型)问题,具体取决于我如何定义 XYZIterator 类型,该类型应该将这些 Iterator 统一到 Vec/Range.

备份方案是分配和return Vecs,但我想知道是否有没有cloning/allocating内存的方法。

type XYZIterator = Box<dyn Iterator<Item = usize>>;

trait XYZ {
    fn stuff(&self) -> XYZIterator;
}

struct Test {
    objects: Vec<usize>,
}
impl XYZ for Test {
    fn stuff(&self) -> XYZIterator {
        Box::new(self.objects.iter())
    }
}

struct Test2 {}
impl XYZ for Test2 {
    fn stuff(&self) -> XYZIterator {
        Box::new((1..4).into_iter())
    }
}

fn main() {
    let t1 = Test {
        objects: vec![1, 2, 3],
    };
    let t2 = Test2 {};

    t1.stuff().for_each(|x| println!("{}", x));
    t2.stuff().for_each(|x| println!("{}", x));
    t1.stuff()
        .filter(|x| x % 2 == 0)
        .for_each(|x| println!("{}", x));
    t2.stuff()
        .filter(|x| x % 2 == 0)
        .for_each(|x| println!("{}", x));
}
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, usize> as Iterator>::Item == usize`
  --> src/main.rs:12:9
   |
12 |         Box::new(self.objects.iter())
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found reference
   |
   = note:   expected type `usize`
           found reference `&usize`
   = note: required for the cast to the object type `dyn Iterator<Item = usize>`

您的代码有两个问题:

  1. 在为 Test1 实现 XYZ 时,您 return 迭代器 self.objects.iter()Vec::iter 遍历 references 到对象,而不是对象本身,所以这是一个遍历 &usize 的迭代器,它与 return 类型不匹配.你应该得到一个关于这个的错误。虽然很容易修复:self.objects.iter().copied() 将从引用中复制每个元素。

  2. type XYZIterator = Box<dyn Iterator<Item = usize>>;中,由于trait对象中没有生命周期,所以默认为'static——也就是说,你的迭代器可以永远存在。但是向量迭代器不是这种情况——它有一个对正在迭代的向量的引用。这是您遇到终身问题的地方。

    解决方案是给 XYZIterator 类型一个生命周期:

    type XYZIterator<'a> = Box<dyn Iterator<Item = usize> + 'a>;
    

    并更改特征和特征实现以使用生命周期。

还可以考虑更改您的类型或函数以接受任何 T: Iterator<Item=usize>;然后它将接受任何产生 usizes

的迭代器