Rust 可选地在自定义迭代器`next()`函数中调用`skip`
我有一个自定义迭代器,我想在自定义Rust 可选地在自定义迭代器`next()`函数中调用`skip`,rust,iterator,Rust,Iterator,我有一个自定义迭代器,我想在自定义.next()方法中选择调用.skip(…)。但是,由于Skip!=迭代器 示例代码如下所示: struct CrossingIter<'a, T> { index: usize, iter: std::slice::Iter<'a, T>, } impl<'a, T: Float> Iterator for CrossingIter<'a, T> { type Item = (usize
.next()
方法中选择调用.skip(…)
。但是,由于Skip!=迭代器
示例代码如下所示:
struct CrossingIter<'a, T> {
index: usize,
iter: std::slice::Iter<'a, T>,
}
impl<'a, T: Float> Iterator for CrossingIter<'a, T> {
type Item = (usize, T);
fn next(&mut self) -> Option<(usize, T)> {
let iter = (&mut self.iter).enumerate();
let iter = if self.index == 0 {
self.index += 3;
iter.skip(3)
} else {
iter
}
// lots of code here working with the new iterator
iter.next()
}
}
struct CrossingIter,
}
恳求{
类型项=(usize,T);
fn下一步(&mut self)->选项{
让iter=(&mut self.iter).enumerate();
设iter=if self.index==0{
自指数+=3;
iter.skip(3)
}否则{
iter
}
//这里有很多使用新迭代器的代码
iter.next()
}
}
问题是调用.skip(3)
后,iter
的类型发生了变化。一种解决方案是在if
语句的每个分支中复制//大量代码…
,但我不希望这样
我的问题是:有没有一种方法可以有条件地对迭代器应用
skip(…)
,并继续使用它而不复制一堆代码?我认为@Silvio的答案是一个更好的观点
您可以在
else
分支中调用skip(0)
而不是iter
本身
由enumerate
生成的迭代器的返回值与您的定义不匹配:fn next(&mut self)->Option
。你需要绘制地图
以下是一个工作示例:
use num::Float;
struct CrossingIter<'a, T> {
index: usize,
iter: std::slice::Iter<'a, T>,
}
impl<'a, T: Float> Iterator for CrossingIter<'a, T> {
type Item = (usize, T);
fn next(&mut self) -> Option<(usize, T)> {
let iter = (&mut self.iter).enumerate();
let mut iter = if self.index == 0 {
self.index += 3;
iter.skip(3)
} else {
iter.skip(0)
};
// lots of code here working with the new iterator
iter.next().map(|(i, &v)| (i, v))
}
}
使用num::Float;
struct CrossingIter,
}
恳求{
类型项=(usize,T);
fn下一步(&mut self)->选项{
让iter=(&mut self.iter).enumerate();
设mut iter=if self.index==0{
自指数+=3;
iter.skip(3)
}否则{
iter.skip(0)
};
//这里有很多使用新迭代器的代码
iter.next().map(|(i和v)|(i,v))
}
}
旨在构造一个新的迭代器,它在希望代码保持(至少在表面上)不可变的情况下非常有用。但是,在您的情况下,您希望在保持现有迭代器有效的同时,使其前进
有一个可以做你想做的,但它是夜间的,所以它不会在稳定的铁锈上运行
if self.index == 0 {
self.index += 3;
self.iter.advance_by(3);
}
我们可以滥用权力来得到我们想要的,但这不是很习惯用语
if self.index == 0 {
self.index += 3;
self.iter.nth(2);
}
如果我在生产中看到这些代码,我会非常困惑
最简单且不太令人满意的答案是将advance\u作为辅助函数重新实现。是可用的,并且很容易适应
fn my_advance_by(iter: &mut impl Iterator, n: usize) -> Result<(), usize> {
for i in 0..n {
iter.next().ok_or(i)?;
}
Ok(())
}
我实际上使用了skip_while(F)
,如果我有两个不同的F
,我又会得到不同的类型……让事情稍微复杂一点,我实际上使用了skip_while(F)
,这取决于一事实,即如果谓词为false,则不会消耗任何内容。我想我可以先把事情看清楚?你的解决方案是否可能是一个简单的for循环,带有next()
和break
?有时,最简单的解决方案可能是最好的,在较低级别的语言中,这一点会加倍,例如RustI尝试了循环
,但由于某些原因,它比使用跳过时慢。也许我应该再试一次,不过……我完全放弃了迭代器,直接在切片上执行了for
循环,自己跟踪索引。这似乎很好地发挥了作用:-)
struct CrossingIter<'a, T> {
index: usize,
iter: std::iter::Skip<std::slice::Iter<'a, T>>,
}