如何在 Rust 中使用 vec 实现过滤器

Dol*_*hin 3 rust

我有一个 vec i64,它存储一些带有一些实体 id 的元素。我想过滤一些指定的实体id并返回一个新的vec。我试图在 rust 中像这样实现这个操作(这是一个最小的例子,真正的元素是一些单词对象):

fn main() {
    let current_word_id:i64 =1;
    let wordIds:Vec<i64> = Vec::new();;
    let current_sentences: Vec<i64> = wordIds
        .iter()
        .filter(|sen| sen == current_word_id)
        .collect();
}
Run Code Online (Sandbox Code Playgroud)

当我编译这段代码时,面临这样的问题:

error[E0277]: can't compare `&&i64` with `i64`
  --> src/main.rs:16:27
   |
16 |         .filter(|sen| sen == current_word_id)
   |                           ^^ no implementation for `&&i64 == i64`
   |
   = help: the trait `PartialEq<i64>` is not implemented for `&&i64`

error[E0277]: a value of type `Vec<i64>` cannot be built from an iterator over elements of type `&i64`
  --> src/main.rs:17:10
   |
17 |         .collect();
   |          ^^^^^^^ value of type `Vec<i64>` cannot be built from `std::iter::Iterator<Item=&i64>`
   |
   = help: the trait `FromIterator<&i64>` is not implemented for `Vec<i64>`

Some errors have detailed explanations: E0277, E0432.
For more information about an error, try `rustc --explain E0277`.
Run Code Online (Sandbox Code Playgroud)

我遵循https://codereview.stackexchange.com/questions/244880/filtering-a-vec-of-structs-and-creating-new-vector-of-strings-or-strs-in-rust。为什么没有按预期工作?我应该做什么才能让它发挥作用?在 Rust 中使用 vec 进行过滤的正确方法是什么?

Ken*_*das 9

所以...这里有一些事情。

迭代时Vec,可以使用 2 种方法 -iter(&self)into_iter(self)。第一个引用Vec并迭代它 - 本质上是对 的视图Vec。第二个消耗Vec并迭代它,在此过程中销毁它并将其转变Vec 迭代器。

您已经使用了第一个,因此您应该处理Vec<i64>或内的引用&i64。过滤器函数不应采用迭代的值,因为这意味着耗尽迭代器,因此它需要对迭代器内的元素的引用(在本例中&i64因此得到 a &&i64)。因此,解决&&i64 == i64问题只需确保类型匹配(即|sen| sen == &&current_word_id或取消引用sen)。

这里的第二部分是,因为您正在&i64像我们之前看到的那样进行迭代,所以这正是您要收集的内容。这可以通过将项目映射到取消引用的值来解决。鉴于这在第一个问题中也是可能的,因此这种映射可以发生在过滤器之前。

把它们放在一起,这个例子可以归结为:

fn main() {
    let current_word_id:i64 =1;
    let wordIds:Vec<i64> = Vec::new();
    let current_sentences: Vec<i64> = wordIds
        .iter()
        .map(|v| *v)
        .filter(|sen| sen == &current_word_id)
        .collect();
}
Run Code Online (Sandbox Code Playgroud)

  • `.map(|v| *v)` 最好写成 [`.copied()`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.复制):) (4认同)