我有一个Vec
,它包含了切片上的迭代器,有些是正常顺序的,有些是相反的。
let mut output = Vec::new();
let input = b"1234567890";
let cuts = [(0,1), (1,3), (3, 5)];
for (start, end) in cuts{
output.push(input[start..end].iter());
output.push(input[start..end].iter().rev());
}
但是我不能编译它,因为
expected struct `std::slice::Iter`, found struct `Rev`
我理解这个错误,但是我不知道,如果我能把这两个迭代器转换成某种公共类型(不用“收集”它们)。
UPD:我甚至尝试使用.iter().rev().rev()
,但它与iter().rev()
是不同的类型...
2条答案
按热度按时间wz1wpwve1#
迭代器和反向迭代器是完全不同的类型,不能直接存储在同一个向量中,它们很可能甚至大小都不一样。
当然,它们都实现了
Iterator
,所以你可以通过间接方式存储它们,或者作为trait对象引用(&dyn Iterator
),或者作为boxed trait对象(Box<dyn Iterator>
),哪一个取决于你的使用情况;第一种是间接费用少,但却是借来的;第二个具有最小的开销,但是拥有对象。在您的例子中,由于您没有保留迭代器对象,而是希望将它们直接存储在列表中,因此正确的解决方案是使用
Box<dyn Iterator>
,如下所示:小毛病:
不鼓励在
&u8
上进行迭代,因为&u8
实际上大于u8
。由于u8
是Copy
,所以将copied()
添加到迭代器中可以减少项大小,而不需要任何成本;甚至很可能具有性能优势。原因是返回
&u8
比返回u8
慢(因为&u8
是4或8字节,而u8
是单字节)。此外,访问&u8
有一个间接寻址,而访问u8
非常快。所以我会这样重写你的代码:
一个二个一个一个
当然,这只对
&u8
适用,对&mut u8
不适用;如果你想改变原来的项目,复制它们会适得其反。kb5ga3dv2#
要将迭代器转换为通用类型,可以使用dynamic dispatch,将trait对象存储到输出向量中:
Playground