I would have thought this was super-simple, but struggling to write a function that produces a generic struct, with the same parameters: playground with below code
struct CapIt<I: Iterator<Item=u64>> {
it: I
}
fn foo<I: Iterator<Item=u64>>() -> CapIt<I> {
let v = vec![0u64, 1];
CapIt {
it: v.into_iter()
}
}
Error:
error[E0308]: mismatched types
--> src/lib.rs:10:13
|
6 | fn foo<I: Iterator<Item=u64>>() -> CapIt<I> {
| - this type parameter
...
10 | it: v.into_iter()
| ^^^^^^^^^^^^^ expected type parameter `I`, found struct `IntoIter`
|
= note: expected type parameter `I`
found struct `std::vec::IntoIter<u64>`
With your generic type argument I you let the caller decide what type to have in your output struct. The caller doesn't decide that though, because you do so in your function by calling v.into_iter(). Instead of letting your caller decide what type I is, decide it yourself with impl Trait in return position. This section of the reference describes what I'm trying to tell you better:
With impl Trait, unlike with a generic type parameter, the function chooses the return type, and the caller cannot choose the return type.
Here is your examle with impl Trait instead of a generic argument:
struct CapIt<I: Iterator<Item=u64>> {
it: I
}
fn foo() -> CapIt<impl Iterator<Item=u64>> {
let v = vec![0u64, 1];
CapIt {
it: v.into_iter()
}
}