为什么将 mut 添加到传递的 Iterator 引用可以解决这个问题?

Xol*_*lve 6 rust

在以下 Rust 片段中:

fn main() {
    let list1: Vec<i32> = vec![0, 1, 2, 3, 4];

    let it1 = list1.iter();
    let tens = it1.map(|x| x * 10).collect::<Vec<i32>>();
    println!("{:?}", tens);
    
    let it2 = list1.iter();
    let doubled_from_iter = scale_it_iter(&it2);

    println!("{:?}", doubled_from_iter);
}

fn scale_it_iter(l: &dyn Iterator<Item = &i32>) -> Vec<i32> {
    l.map(|x| x * 2).collect()
}
Run Code Online (Sandbox Code Playgroud)

Rust 游乐场链接

我收到此错误:

error: the `map` method cannot be invoked on a trait object
   --> src/main.rs:15:7
    |
15  |     l.map(|x| x * 2).collect()
    |       ^^^
    |
   ::: /home/xolve/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:625:15
    |
625 |         Self: Sized,
    |               ----- this has a `Sized` requirement
    |
    = note: you need `&mut dyn Iterator<Item = &i32>` instead of `&dyn Iterator<Item = &i32>`

error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)

mut按照编译器的建议添加解决了这个问题。工作代码的 Rust Playground 链接

我不明白为什么需要它。main当我打电话时不需要它it1.map

我不明白错误信息。

  1. the `map` method cannot be invoked on a trait object通过添加mut到特征引用来解决。这似乎是矛盾的。
  2. 关于Sizedtrait bound的消息如何与错误相关?

kmd*_*eko 5

map方法不能性状对象上被调用”“这有一个Sized要求”错误消息是因为消耗的原始迭代器。s不能被消耗(它们是未定义大小的类型,不能按值传递给函数)。map() dyn Trait

it1之所以有效,是因为 1)它不是一个 trait 对象,它是一个具体类型Iter,2)它不是一个引用,所以它被消耗了。

有效的原因&mut dyn Iterator是因为&mut dyn Iterator实现了Iterator. 有效的区别只是引用被消耗并且底层迭代器发生了变化。


如果您想遵循约定,我会像这样scale_it_iter 使用迭代器:

fn scale_it_iter<'a>(l: impl Iterator<Item = &'a i32>) -> Vec<i32> {
    l.map(|x| x * 2).collect()
}
Run Code Online (Sandbox Code Playgroud)