我正在尝试使用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!("");
}
Run Code Online (Sandbox Code Playgroud)
哪个印刷品:
None
Some(2)
None
None
Some(2)
None
Run Code Online (Sandbox Code Playgroud)
迭代器i1
正在回归我的期望.它返回None
,然后Some(2)
,然后None
.i2
是同样的迭代器适应fuse()
.保险丝应该None
在第一个之后返回None
,因为它返回的第一个值None
应该是它返回的唯一值.但是,它的行为与...相同i1
.我究竟做错了什么?
我很确定你做错了什么.这似乎是一个错误(我的猜测)或一个非常令人困惑的互动.看看这个扩展的例子:
#![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());
}
Run Code Online (Sandbox Code Playgroud)
诀窍在于,这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> {}
Run Code Online (Sandbox Code Playgroud)
确实如果底层迭代器是FusedIterator
并且开始返回None
,scan
将继续返回None
.然而,这不是获得的唯一途径None
- 关闭也可以返回None
!
归档时间: |
|
查看次数: |
162 次 |
最近记录: |