Почему я могу создать итератор в штучной упаковке из Vec, а не из массива?
Приведенный ниже код компилируется, но если аргументы, переданные функции f, изменяются с Vec на массив строк, этого не происходит. Я пытаюсь понять почему. Я предполагаю, что это как-то связано с правилами владения, но я мог бы использовать некоторые пояснения. Спасибо.
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()));
}
Если vec!["One_arg".to_string()]; заменяется на: ["one_arg".to_string()];, приведенная ниже ошибка является результатом.
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>`
1 ответ
Решение
Причина в том, что Vec::into_iter
возвращает итератор по своим элементам, а slice::into_iter
возвращает итератор по ссылкам на свои элементы. Так,args.into_iter()
является Iterator<Item=&String>
вместо того Iterator<Item=String>
когда args
это кусок. Кстати, неBox
а dyn Iterator
а вместо этого просто используйте общий:
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());
}