iterator - 为什么在具有推断 Item 类型的 Iter 上调用 cloned() 允许将其传递到此函数中?

标签 iterator rust

我试图了解一点 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/

相关文章:

c++ - 如何使用迭代器修改对象?使用 <列表>

c++ - 使用反向迭代器在 C++ 中反转字符串?

c++ - 仅通过迭代器删除 STL 容器元素

c++ - 检查模板参数是否为 std::vector<T>::iterator

python - 从 Python 中的生成器获取多个单独的值

rust - 对我的可写类型使用 fmt::Write 或 io::Write trait?

rust - 如何在 HashMap 字段中保存对处理程序的引用

string - Rust 中的切片和引用之间的关系是什么?

closures - 如何为闭包参数声明更高级别的生命周期?

rust - Rust 中的红黑树,得到 'expected struct Node, found mutable reference'