私は、イテレータを受け取り、その上でいくつかの演算の結果を返す関数を記述したいと思います。具体的には、私はHashMap
の値を反復しようとしています:イテレータをとる錆関数を書くには?
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
を使用すると、生涯エラーが発生します。
私はとても近くでした。解説すると、ジェネリックとの違いは静的ディスパッチです。つまり、私はそれを呼び出す具体的なタイプごとにこの関数のバージョンを作成していますか? –
正しい。このように、コンパイラはイテレータの型を知っているので、そのサイズを知っているので、どのくらいのメモリを確保する必要があるのかが分かります。また、 'Iterator- 'のような型は単独では使用できません。ポインタの後ろでしか使用できません。 –
任意のイテレータを関数に渡したい場合は、 'Iterator'を実装するために' I'を必要としますが、より汎用的な方法は '' IntoIterator''(http:// doc.rust-lang.org/std/iter/trait.IntoIterator.html)。イテレータも渡すことができますが、変換メソッドを明示的に呼び出す必要はなく、イテレータに変換できるものを渡すこともできます。私はイテレータとiterablesを消費する*慣用的なアプローチだと言っています。 –