我试图了解一点 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);
据我所知,错误表明编译器无法安全地推断出我试图作为参数传递的项目的类型,但为什么调用 cloned() 或 map 会改变任何东西?
最佳答案
您的 print
函数需要一个 usize
的迭代器作为参数,但是 it
(在您的第一个版本中)是一个迭代器,它产生&usize
值,即对 usize
的引用。
clone()
本质上是将 Clone::clone
映射到迭代器上,因此它将 &T
的迭代器转换为 的迭代器>T
,以便修复程序中的类型不匹配问题。
您的最终版本(let it = a.iter().map(|&x| x);
)还将迭代器从 &T
的迭代器转换为T
的迭代器,但这次是通过使用模式匹配取消引用元素。
由于 print
实际上不需要拥有迭代器的元素,您还可以通过将其类型更改为以下内容来解决您的问题:
fn print<'a, I: Iterator<Item=&'a usize>>(iter: I)
关于iterator - 为什么在具有推断 Item 类型的 Iter 上调用 cloned() 允许将其传递到此函数中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30943116/