snippetrustCritical
How to write a Rust function that takes an iterator?
Viewed 0 times
takeshowfunctionwriteiteratorrustthat
Problem
I'd like to write a function that accepts an iterator and returns the results of some operations on it. Specifically, I'm trying to iterate over the values of a
But alas:
I get the same error if I try to pass by reference; if I use a
HashMap:use std::collections::HashMap;
fn find_min(vals: Iterator) -> Option {
vals.min()
}
fn main() {
let mut map = HashMap::new();
map.insert("zero", 0u32);
map.insert("one", 1u32);
println!("Min value {:?}", find_min(map.values()));
}But alas:
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 + 'static: std::marker::Sized is not satisfied
--> src/main.rs:3:17
|
3 | fn find_min(vals: Iterator) -> Option {
| ^^^^ std::iter::Iterator + 'static does not have a constant size known at compile-time
|
= help: the trait std::marker::Sized is not implemented for std::iter::Iterator + '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 + 'static
found type std::collections::hash_map::Values
I get the same error if I try to pass by reference; if I use a
Box, I get lifetime errors.Solution
You want to use generics here:
Traits can be used in two ways: as bounds on type parameters and as trait objects. The book The Rust Programming Language has a chapter on traits and a chapter on trait objects that explain these two use cases.
Additionally, you often want to take something that implements
fn find_min(vals: I) -> Option
where
I: Iterator,
{
vals.min()
}Traits can be used in two ways: as bounds on type parameters and as trait objects. The book The Rust Programming Language has a chapter on traits and a chapter on trait objects that explain these two use cases.
Additionally, you often want to take something that implements
IntoIterator as this can make the code calling your function nicer:fn find_min(vals: I) -> Option
where
I: IntoIterator,
{
vals.into_iter().min()
}Code Snippets
fn find_min<'a, I>(vals: I) -> Option<&'a u32>
where
I: Iterator<Item = &'a u32>,
{
vals.min()
}fn find_min<'a, I>(vals: I) -> Option<&'a u32>
where
I: IntoIterator<Item = &'a u32>,
{
vals.into_iter().min()
}Context
Stack Overflow Q#34969902, score: 119
Revisions (0)
No revisions yet.