Reputation: 5313
I would like to do the following and allow my perform
function to take an iterator with &usize
or with usize
items as below.
fn perform<'a, I>(values: I) -> usize
where
I: Iterator<Item = &'a usize>,
{
*values.max().unwrap()
}
fn main() {
let v: Vec<usize> = vec![1, 2, 3, 4];
// Works.
let result = perform(v.iter());
print!("Result: {}", result);
// Does not work: `expected `&usize`, found `usize``.
let result = perform(v.iter().map(|v| v * 2));
print!("Result again: {}", result)
}
Playground example here.
Upvotes: 1
Views: 35
Reputation: 3396
Another way may be accepting owned values in perform
like this:
fn perform<I>(values: I) -> usize
where
I: Iterator<Item = usize>,
{
values.max().unwrap()
}
fn main() {
let v: Vec<usize> = vec![1, 2, 3, 4];
// Works.
let result = perform(v.iter().map(|x| *x));
print!("Result: {}", result);
// Does not work: `expected `&usize`, found `usize``.
let result = perform(v.iter().map(|v| v * 2));
print!("Result again: {}", result)
}
Upvotes: 2
Reputation: 70267
In this case, by making your function more polymorphic, we actually get the behavior for free. Your perform
works for any Ord
value.
fn perform<'a, I, T>(values: I) -> T
where
I: Iterator<Item = T>,
T: Ord,
{
values.max().unwrap()
}
Now usize
is Ord
and so is &usize
(by a blanket impl
that makes references to any orderable type orderable).
Upvotes: 3