我正在尝试使用Fuse
迭代器适配器,并且得到了意外的结果(Playground链接):
fn main() {
let mut i1 = (1..3).scan(1, |_, x| {
if x < 2 { None } else { Some(x) }
});
println!("{:?}", i1.next());
println!("{:?}", i1.next());
println!("{:?}", i1.next());
println!("");
let mut i2 = (1..3).scan(1, |_, x| {
if x < 2 { None } else { Some(x) }
}).fuse();
println!("{:?}", i2.next());
println!("{:?}", i2.next()); // This should print None
println!("{:?}", i2.next());
println!("");
}
哪些打印:
None
Some(2)
None
None
Some(2)
None
迭代器i1
返回了我期望的结果。它返回None
,然后Some(2)
,然后None
。i2
与相同的迭代器fuse()
。保险丝应使其None
在第一个之后返回None
,并且由于它返回的第一个值是None
它应该返回的唯一值。但是,其行为与相同i1
。我究竟做错了什么?
TL; DR摘要:这是一个错误,已在Rust 1.19和更高版本中修复。
我很确定您没有做错任何事情。这似乎是一个错误(我的猜测)或一个非常令人困惑的交互。查看以下扩展示例:
#![feature(fused)]
fn dump<I: Iterator<Item = i32>>(label: &str, mut iter: I) {
println!("= Running: {}", label);
for _ in 0..10 {
println!("{:?}", iter.next());
}
println!("");
}
fn boxed_internal_fuse() -> Box<Iterator<Item = i32>> {
Box::new((1..3)
.scan(1, |_, x| if x < 2 { None } else { Some(x) })
.fuse())
}
fn boxed_no_fuse() -> Box<Iterator<Item = i32>> {
Box::new((1..3)
.scan(1, |_, x| if x < 2 { None } else { Some(x) }))
}
use std::iter::FusedIterator;
fn boxed_no_fuse_but_fused() -> Box<FusedIterator<Item = i32>> {
Box::new((1..3)
.scan(1, |_, x| if x < 2 { None } else { Some(x) }))
}
fn main() {
let i1 = (1..3)
.scan(1, |_, x| if x < 2 { None } else { Some(x) });
dump("Scan", i1);
let i2 = (1..3)
.scan(1, |_, x| if x < 2 { None } else { Some(x) })
.fuse();
dump("Fuse<Scan>", i2);
dump("Box<Fuse<Scan>>", boxed_internal_fuse());
dump("Fuse<Box<Iterator>>", boxed_no_fuse().fuse()); // All `None`s
dump("Fuse<Box<FusedIterator>>", boxed_no_fuse_but_fused().fuse());
}
诀窍在于这FusedIterator
是一个不稳定的特征,旨在提高效率。它让我们Iterator::fuse
知道这是无人值守的。
但是,在这种情况下,条件是必要的,但还不够:
impl<B, I, St, F> FusedIterator for Scan<I, St, F>
where I: FusedIterator, F: FnMut(&mut St, I::Item) -> Option<B> {}
的确,如果基础迭代器是FusedIterator
并且开始返回None
,则scan
它将继续返回None
。但是,这并不是唯一的方法None
-闭包也可以返回None
!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句