我想编写一个接受迭代器并返回一些操作结果的函数。具体来说,我想遍历一个HashMap
值:如何编写一个需要迭代器的Rust函数?
use std::collections::HashMap;
fn find_min<'a>(vals: Iterator<Item=&'a u32>) -> Option<&'a u32> {
vals.min()
}
fn main() {
let mut map = HashMap::new();
map.insert("zero", 0u32);
map.insert("one", 1u32);
println!("Min value {:?}", find_min(map.values()));
}
但可惜:
error: the `min` method cannot be invoked on a trait object
--> src/main.rs:4:10
|
4 | vals.min()
| ^^^
error[E0277]: the trait bound `std::iter::Iterator<Item=&'a u32> + 'static: std::marker::Sized` is not satisfied
--> src/main.rs:3:17
|
3 | fn find_min<'a>(vals: Iterator<Item = &'a u32>) -> Option<&'a u32> {
| ^^^^ `std::iter::Iterator<Item=&'a u32> + 'static` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `std::iter::Iterator<Item=&'a u32> + 'static`
= note: all local variables must have a statically known size
error[E0308]: mismatched types
--> src/main.rs:11:41
|
11 | println!("Min value {:?}", find_min(map.values()));
| ^^^^^^^^^^^^ expected trait std::iter::Iterator, found struct `std::collections::hash_map::Values`
|
= note: expected type `std::iter::Iterator<Item=&u32> + 'static`
found type `std::collections::hash_map::Values<'_, &str, u32>`
我得到同样的错误,如果我尝试按引用传递;如果我使用Box
,我会遇到生命期错误。
我太亲近了。为了说明,与泛型的区别是静态分派,即Rust为我调用的每个具体类型创建了此函数的一个版本? –
正确。这样,编译器知道迭代器的类型,因此它知道它的大小,所以它知道需要预留多少内存。另外,像Iterator- '这样的类型不能单独使用;它只能在指针后面使用。 –
请注意,虽然要求'I'实现'Iterator'是绝对正确的,如果你想传递任意迭代器到函数中,更通用的方法是要求'I'实现['IntoIterator'](http:// doc.rust-lang.org/std/iter/trait.IntoIterator.html)。它允许你也传递迭代器,但你也可以将任何可以被转换的东西传递给一个迭代器,而不需要明确地调用转换方法。我会说这是消费迭代器和迭代器的常用方法。 –