如何迭代和过滤数组? [英] How to iterate over and filter an array?

查看:31
本文介绍了如何迭代和过滤数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个涉及过滤和折叠数组的程序.我一直在使用 Rust 编程语言,第一版 作为参考,但我不明白当我在数组上形成迭代器时会发生什么.下面是一个例子:

I'm trying to write a program that involves filtering and folding over arrays. I've been using The Rust Programming Language, first edition as a reference, but I don't understand what happens when I form iterators over arrays. Here is an example:

fn compiles() {
    let range = (1..6);
    let range_iter = range.into_iter();
    range_iter.filter(|&x| x == 2);
}

fn does_not_compile() {
    let array = [1, 4, 3, 2, 2];
    let array_iter = array.into_iter();
    //13:34 error: the trait `core::cmp::PartialEq<_>` is not implemented for the type `&_` [E0277]
    array_iter.filter(|&x| x == 2);
}

fn janky_workaround() {
    let array = [1, 4, 3, 2, 2];
    let array_iter = array.into_iter();
    // Note the dereference in the lambda body
    array_iter.filter(|&x| *x == 2);
}

(Rust 游乐场)

在第一个函数中,我遵循范围内的迭代器不拥有所有权,因此我必须在 filter 的 lambda 中使用 &x,但是我不明白为什么带有数组的第二个示例的行为不同.

In the first function, I follow that the iterator over the range does not take ownership, so I must take a &x in filter's lambda, but I don't understand why the second example with the array behaves differently.

推荐答案

在这种情况下,强制编译器告诉您变量的类型非常有用.让我们通过将闭包参数分配给不兼容的类型来触发类型错误:

In cases like this, it's very useful to force the compiler to tell you the type of the variable. Let's trigger a type error by assigning the closure argument to an incompatible type:

array_iter.filter(|x| { let _: () = x; x == 2 });

这失败了:

error[E0308]: mismatched types
 --> src/lib.rs:4:41
  |
4 |     array_iter.filter(|x| { let _: () = x; x == 2 });
  |                                    --   ^ expected `()`, found `&&{integer}`
  |                                    |
  |                                    expected due to this

现在我们知道 x 的类型是 &&{integer} - 对 some 类型的引用的引用整数.然后我们可以与之匹配:

Now we know the type of x is a &&{integer} - a reference to a reference to some kind of integer. We can then match against that instead:

fn hooray() {
    let array = [1, 4, 3, 2, 2];
    let array_iter = array.into_iter();
    array_iter.filter(|&&x| x == 2);
}

现在的问题变成了为什么它是对引用的引用"?简短的版本是 迭代器返回引用(参见 type Item = &'a T 部分).另外,Iterator::filter 将引用 传递给闭包,以防止移动并随后丢失非Copy 类型.

The question now becomes "why is it a reference to a reference"? The short version is that the iterator of an array returns references (see the type Item = &'a T part). In addition, Iterator::filter passes a reference to the closure to prevent moving and subsequently losing non-Copy types.

在 Rust 1.51 中,您可以使用 array::IntoIter 得到一个按值迭代器:

In Rust 1.51, you can use array::IntoIter to get a by-value iterator:

fn hooray() {
    let array = [1, 4, 3, 2, 2];
    let array_iter = std::array::IntoIter::new(array);
    array_iter.filter(|&x| x == 2);
}

这篇关于如何迭代和过滤数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆