我如何应对惰性迭代器?
How do I cope with lazy iterators?
我正在尝试使用 map()
在迭代器上对数组进行排序。
struct A {
b: Vec<B>,
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct B {
c: Vec<i32>,
}
fn main() {
let mut a = A { b: Vec::new() };
let b = B { c: vec![5, 2, 3] };
a.b.push(b);
a.b.iter_mut().map(|b| b.c.sort());
}
给出警告:
warning: unused `std::iter::Map` that must be used
--> src/main.rs:16:5
|
16 | a.b.iter_mut().map(|b| b.c.sort());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default
= note: iterators are lazy and do nothing unless consumed
没错,sort()
实际上并没有在这里调用。 book 中描述了此警告,但我不明白为什么 iter_mut()
的这种变体可以正常工作:
a.b.iter_mut().find(|b| b == b).map(|b| b.c.sort());
I don't understand why this variation with iter_mut()
works fine:
a.b.iter_mut().find(|b| b == b).map(|b| b.c.sort());
之所以有效,是因为find
不懒惰;它是一个迭代器消费者。它 return 是 Option
而不是 Iterator
。这可能就是让您感到困惑的原因,因为 Option
也有一个 map
方法,这就是您在这里使用的方法。
正如其他人所说,map
用于转换数据,无需修改数据,也无需任何其他 side-effects。如果真的要用map
,可以map over collection再赋值回去:
fn main() {
let mut a = A { b: Vec::new() };
let mut b = B { c: vec![5, 2, 3] };
a.b.push(b);
a.b =
a.b.into_iter()
.map(|mut b| {
b.c.sort();
b
})
.collect();
}
请注意向量的 sort
方法 returns ()
,因此您必须显式 return 来自映射函数的排序向量。
正如您链接到的那本书所说:
If you are trying to execute a closure on an iterator for its side effects, use for
instead.
这样就可以了,任何阅读代码的人都清楚得多。当你想将一个向量转换为另一个向量时,你应该使用 map
。
我用for_each
。
根据文档:
It is equivalent to using a for
loop on the iterator, although break
and continue
are not possible from a closure. It's generally more idiomatic to use a for
loop, but for_each
may be more legible when processing items at the end of longer iterator chains. In some cases for_each
may also be faster than a loop, because it will use internal iteration on adaptors like Chain
.
我正在尝试使用 map()
在迭代器上对数组进行排序。
struct A {
b: Vec<B>,
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct B {
c: Vec<i32>,
}
fn main() {
let mut a = A { b: Vec::new() };
let b = B { c: vec![5, 2, 3] };
a.b.push(b);
a.b.iter_mut().map(|b| b.c.sort());
}
给出警告:
warning: unused `std::iter::Map` that must be used
--> src/main.rs:16:5
|
16 | a.b.iter_mut().map(|b| b.c.sort());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default
= note: iterators are lazy and do nothing unless consumed
没错,sort()
实际上并没有在这里调用。 book 中描述了此警告,但我不明白为什么 iter_mut()
的这种变体可以正常工作:
a.b.iter_mut().find(|b| b == b).map(|b| b.c.sort());
I don't understand why this variation with
iter_mut()
works fine:a.b.iter_mut().find(|b| b == b).map(|b| b.c.sort());
之所以有效,是因为find
不懒惰;它是一个迭代器消费者。它 return 是 Option
而不是 Iterator
。这可能就是让您感到困惑的原因,因为 Option
也有一个 map
方法,这就是您在这里使用的方法。
正如其他人所说,map
用于转换数据,无需修改数据,也无需任何其他 side-effects。如果真的要用map
,可以map over collection再赋值回去:
fn main() {
let mut a = A { b: Vec::new() };
let mut b = B { c: vec![5, 2, 3] };
a.b.push(b);
a.b =
a.b.into_iter()
.map(|mut b| {
b.c.sort();
b
})
.collect();
}
请注意向量的 sort
方法 returns ()
,因此您必须显式 return 来自映射函数的排序向量。
正如您链接到的那本书所说:
If you are trying to execute a closure on an iterator for its side effects, use
for
instead.
这样就可以了,任何阅读代码的人都清楚得多。当你想将一个向量转换为另一个向量时,你应该使用 map
。
我用for_each
。
根据文档:
It is equivalent to using a
for
loop on the iterator, althoughbreak
andcontinue
are not possible from a closure. It's generally more idiomatic to use afor
loop, butfor_each
may be more legible when processing items at the end of longer iterator chains. In some casesfor_each
may also be faster than a loop, because it will use internal iteration on adaptors likeChain
.