如何迭代和过滤数组?

时间:2015-05-26 19:19:13

标签: rust

我试图编写一个涉及过滤和折叠数组的程序。我一直在使用The Rust Programming Language, first edition作为参考,但我不明白当我在数组上形成迭代器时会发生什么。这是一个例子:

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 playground

在第一个函数中,我遵循范围内的迭代器不占用所有权,因此我必须在&x的lambda中使用filter,但我不会这样做。理解为什么数组的第二个例子表现不同。

3 个答案:

答案 0 :(得分:30)

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

array_iter.filter(|x| { let () = x; true });

这失败了:

error[E0308]: mismatched types
  --> src/main.rs:12:33
   |
12 |     array_iter.filter(|x| { let () = x; true });
   |                                 ^^ expected &&{integer}, found ()
   |
   = note: expected type `&&{integer}`
              found type `()`

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

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

现在问题变成&#34;为什么它是对参考的引用&#34;?简短版本是iterator of an array returns references(参见type Item = &'a T部分)。此外,Iterator::filter passes a reference关闭以阻止移​​动并随后丢失非Copy类型。

答案 1 :(得分:22)

数组是Rust中的类型[T; N],适用于任何元素类型T和常量数N。这是一个固定大小的阵列。

Rust目前没有为数组实现按值迭代器。所有数组都强制转换为切片(类型[T]),并且切片方法因此而在数组上可用。数组也得到切片的迭代器,它被称为std::slice::Iter<'a, T>并且具有&'a T类型的元素:它通过引用迭代!

这就是为into_iter()上的Range<i32>生成i32的迭代器而into_iter()上的[i32; 5]生成&i32的迭代器的原因。

如果您需要数组的值迭代器,它们已在更广泛的生态系统中实现,请参阅(1)(2)

答案 2 :(得分:1)

正如Shepmaster和bluss所说,你可以查看提到的documentation for the array type

  

大小从0到32(含)的数组实现以下内容   如果元素类型允许,则为traits:

     
      
  • IntoIterator(已针对&[T; N]&mut [T; N]实施)
  •   

正如它所说,这仅适用于参考,并反映在Item类型中:type Item = &'a Ttype Item = &'a mut T