Reputation: 190
I know that the cloned()
here is unnecessary but I want to know why it requires that Values
implement the Iterator
trait.
Minimal reproducible example
#[derive(Debug, Clone)]
enum Values {
Foo,
Bar
}
fn f(mut values: impl Iterator<Item=Values>) {
// (HERE) Why to clone Option<Values> should implement Iterator???
if let Some(v1) = values.next().cloned() {
if let Some(v2) = values.next() {
println!("Foo");
}
}
}
fn main() {
let mut values = vec![
Values::Foo,
Values::Bar
];
f(values.into_iter());
}
Error
error[E0599]: the method `cloned` exists for enum `Option<Values>`, but its trait bounds were not satisfied
--> src/main.rs:8:37
|
8 | if let Some(v1) = values.next().cloned() {
| ^^^^^^ method cannot be called on `Option<Values>` due to
unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`Option<Values>: Iterator`
which is required by `&mut Option<Values>: Iterator`
Playground link
Upvotes: 3
Views: 12961
Reputation: 58735
Option::cloned()
is only defined if the value inside is a reference. For example, you could call it if the paramters was values: impl Iterator<Item = &Values>
, which would make the result of next()
an Option<&Values>
.
You parameter values: impl Iterator<Item = Values>
means that the iterator owns the values. The values are moved out of the iterator as you iterate through it so the clone would be unnecessary. I assume that this is just an artifact of it being a minimum reproducible example.
The error is confusing because the compiler is trying to help you by suggesting traits you could implement that do have a cloned()
method, and the choices are:
Option<&T>
I
where I: Iterator<Item = &T>
It unfortunately has chosen the one that doesn't apply in your situation.
Upvotes: 3
Reputation: 2583
There are two applicable cloned
functions, Iterator::cloned
and Option::cloned
.
The Option::cloned
does not apply in this case, since it is only available for types like Option<&T>
. In the example it is a Option<Value>
which is not a reference.
Iterator::cloned
could apply, if the trait bound Option<Values>: Iterator
is satisfied, which is why this is part of the suggestion.
Both functions would be wrong in this context to use.
Maybe you meant to use the clone
function which would indeed be unnecessary.
Upvotes: 4