【问题标题】:Rust Error: value of type `std::vec::Vec<i32>` cannot be built from `std::iter::Iterator<Item=&i32>`Rust 错误:`std::vec::Vec<i32>` 类型的值不能从 `std::iter::Iterator<Item=&i32>` 构建
【发布时间】:2020-10-04 20:51:54
【问题描述】:

我是 rust 新手,遇到了错误

std::vec::Vec&lt;i32&gt; 不能从 std::iter::Iterator&lt;Item=&amp;i32&gt; 构建

当尝试使用函数 get_even_numbers() 借用 v 时,通过引用 &amp;v 而不是值 v 传递它。

fn main() {
    let v: Vec<i32> = (0..10).collect();
    let even: Vec<i32> = get_even_numbers(&v);
    println!("Even numbers: {:?}", even);
}

fn get_even_numbers(v: &Vec<i32>) -> Vec<i32> {
    v.iter().filter(|x| x % 2 == 0).collect()
}

为什么上面会报错,而按值传入却没有,如下图?

另外,我在通过引用传入时在函数内部使用了.iter(),在通过值传入时使用了.into_iter(),不确定这些函数是否正确。

fn main() {
    let v: Vec<i32> = (0..10).collect();
    let even: Vec<i32> = get_even_numbers(v);
    println!("Even numbers: {:?}", even);
}

fn get_even_numbers(v: Vec<i32>) -> Vec<i32> {
    v.into_iter().filter(|x| x % 2 == 0).collect()
}

// Even numbers: [0, 2, 4, 6, 8]

【问题讨论】:

  • 遍历借来的向量会遍历对值的引用。分发实际值需要将它们从向量中移出,并且只有在过程中消耗了向量本身时才允许这样做。这就是为什么带有into_iter() 的版本可以工作的原因——因为into_iter() 使用了向量,它确实将向量元素的所有权传递给了迭代器的消费者。由于i32Copy,您可以通过添加取消引用来修复借用的版本,例如通过将.collect() 更改为.copied().collect()

标签: rust reference


【解决方案1】:

使用v.iter().filter(|x| x % 2 == 0).cloned().collect()。这将(简单地)将每个 &amp;i32 引用克隆为实际的 i32 值。

【讨论】:

  • 您可以使用copied() 而不是cloned() 来断言(在编译时)克隆是微不足道的。
猜你喜欢
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
相关资源
最近更新 更多