1. ホーム
  2. function

[解決済み] イテレータを受け取るRust関数はどう書けばいい?

2023-03-15 21:07:36

質問

イテレータを受け取り、それに対するいくつかの操作の結果を返す関数を書きたいと思っています。 具体的には、私は 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 を使用すると、ライフタイムエラーが発生します。

どのように解決するのですか?

ここではジェネリックを使いたい。

fn find_min<'a, I>(vals: I) -> Option<&'a u32>
where
    I: Iterator<Item = &'a u32>,
{
    vals.min()
}

traitは型パラメータの境界として、またtraitオブジェクトとして、2つの方法で使用することができます。本 Rust プログラミング言語 の章では 特性 の章と 特性オブジェクト の章を設け、この2つのユースケースを説明しています。

さらに、あなたはしばしば IntoIterator を実装しているものを取りたいと思うことがあります。

fn find_min<'a, I>(vals: I) -> Option<&'a u32>
where
    I: IntoIterator<Item = &'a u32>,
{
    vals.into_iter().min()
}