The code below compiles, but if the args
passed to the function f
is changed from a vector of strings to an array of strings it does not. I'm trying to understand why. I assume it has something to do with the ownership rules, but I could use some clarification.
fn f(args: Box<dyn Iterator<Item=String>>) {
for arg in args {
println!("{}", arg)
}
}
fn main() {
let args = vec!["one_arg".to_string()]; // If changed to array, I get error below
f(Box::new(args.into_iter()));
}
If vec!["one_arg".to_string()]
is changed to ["one_arg".to_string()]
, I get the error below:
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, std::string::String> as std::iter::Iterator>::Item == std::string::String`
--> src/main.rs:10:7
|
10 | f(Box::new(args.into_iter()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found reference
|
= note: expected struct `std::string::String`
found reference `&std::string::String`
= note: required for the cast to the object type `dyn std::iter::Iterator<Item = std::string::String>`
The reason is because Vec::into_iter
returns an iterator over its items, while slice::into_iter
returns an iterator over references to its items. So, args.into_iter()
is an Iterator<Item=&String>
instead of Iterator<Item=String>
when args
is a slice. On a side note, don't Box
a dyn Iterator
and instead just use a generic:
fn f<I: Iterator<Item=String>>(args: I) {
for arg in args {
println!("{}", arg)
}
}
fn main() {
let args = vec!["one_arg".to_string()];
f(args.into_iter());
}