我试图了解Iterator及其工作原理,我希望你们中的一些人可以向我解释这段代码:
fn main() {
let a: Vec<_> = (0..10).map(|_| 2).collect();
let it = a.iter();
print(it);
}
fn print<I: Iterator<Item=usize>>(iter: I) {
for x in iter {
println!("{}",x);
}
}
我知道上面的代码非常复杂,但它是我从更复杂的版本创建的简单代码,它更有意义,只是为了找到问题的核心并更好地理解它。
在rustc中编译此代码时,我遇到了这个编译错误:
src/main.rs:5:5: 5:8 error: type mismatch resolving `<core::slice::Iter<'_, _> as core::iter::Iterator>::Item == usize`:
expected &-ptr,
found usize [E0271]
src/main.rs:5 print(it);
^~~
我通过改变let来修复它:
let it = a.iter().cloned();
或
let it = a.iter().map(|&x| x);
据我所知,错误表明编译器无法安全地推断出我试图传递的Item的类型作为参数,但为什么调用cloned()或map会改变什么?
答案 0 :(得分:2)
您的print
函数需要usize
的迭代器作为参数,但it
(在您的第一个版本中)是一个产生&usize
值的迭代器,即引用到usize
。
cloned()
实际上将Clone::clone
映射到迭代器上,因此它将&T
的迭代器转换为T
的迭代器,以便修复程序中的类型不匹配。
您的最终版本(let it = a.iter().map(|&x| x);
)也将迭代器从&T
的迭代器转换为T
的迭代器,但这次是通过使用模式匹配解除引用元素。
由于print
实际上不需要拥有迭代器的元素,因此您还可以通过将其类型更改为以下内容来解决问题:
fn print<'a, I: Iterator<Item=&'a usize>>(iter: I)