How to iterate over and filter an array?

后端 未结 3 1397
耶瑟儿~
耶瑟儿~ 2020-11-30 08:18

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 un

相关标签:
3条回答
  • 2020-11-30 08:53

    Arrays are the type [T; N] in Rust, for any element type T and a constant number N. It's a fixed size array.

    Rust doesn't implement by-value iterators for arrays at the moment. All arrays coerce to slices (type [T]) and the slice methods are available on the array because of this. The arrays also get the slice's iterator, which is called std::slice::Iter<'a, T> and has elements of type &'a T: it iterates by reference!

    This is why into_iter() on a Range<i32> produces an iterator of i32 and into_iter() on a [i32; 5] produces an iterator of &i32.

    If you need by value iterators for arrays, they have been implemented in the broader ecosystem, see (1) and (2).

    0 讨论(0)
  • 2020-11-30 08:54

    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; true });
    

    This fails with:

    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 `()`
    

    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);
    }
    

    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.

    0 讨论(0)
  • 2020-11-30 09:13

    As Shepmaster and bluss said, you can check the documentation for the array type, which mentions:

    Arrays of sizes from 0 to 32 (inclusive) implement the following traits if the element type allows it:

    • IntoIterator (implemented for &[T; N] and &mut [T; N])

    As it says, this is only for references, and is reflected in its Item type: type Item = &'a T and type Item = &'a mut T.

    0 讨论(0)
提交回复
热议问题