DEV Community

BC
BC

Posted on

Day22:iter, map, for_each, filter & closure - 100DayOfRust

I posted an article about Closure before, but in that article I was still confused inside the closure function, when to use |x|, |&x| and |&&x|, and inside the closure when to use x, *x and **x.

After did some search and experiments, here is what I got:

methods

  • iter: return reference to original value
  • into_iter: return the original value (ownership)
  • range: return an into_iter (i.e. the original value, not the reference)

  • any: won't return reference

  • map: won't return reference

  • for_each: wont' return reference

  • filter: return reference

  • find: return reference

Examples

For functions that don't use reference: any, for_each, map

let numbers = vec![1,2,3];
numbers.iter().for_each(|x| {
    // iter will return reference
    // for_each won't return reference
    // so x is one-layer reference, which is &integer
    // to get the origin value, we could use *x
    println!("number is {}", *x);
});
Enter fullscreen mode Exit fullscreen mode

For functions that use reference: filter and find

let numbers = vec![1,2,3];
let even_numbers = numbers.iter().filter(|x| {
    // iter will return reference
    // filter will return reference
    // so x is two-layer reference, which is &&integer
    // to get the origin value, we could use **x
    **x % 2 == 0
}).collect();
Enter fullscreen mode Exit fullscreen mode

For iterators that don't return reference: into_iter, range

let numbers = vec![1,2,3];
numbers.into_iter().for_each(|x| {
    // into_iter will return the original value
    // so here x is integer, not &integer
    println!("number is {}", x);
});
Enter fullscreen mode Exit fullscreen mode

Another example:

let numbers = vec![1,2,3];
numbers.into_iter().filter(|x| {
    // into_iter will return the original value
    // filter will return reference
    // so here x is &integer, not &&integer
});
Enter fullscreen mode Exit fullscreen mode

Range will return a into_iter, for example:

let even_numbers: Vec<i32> = (0..10).filter(|x| {
    // range will return the original value
    // filter will return reference
    // x is one-layer reference, which is &integer
    // to get the actual value, use *x
    *x % 2 == 0
});
Enter fullscreen mode Exit fullscreen mode

Reference

Top comments (2)

Collapse
 
bitecode profile image
BC

As I checked more example on this, the into_iter() on array will actually return a reference, not ownership, that's so inconsistent with Vector, why Rust do this?

fn main() {
    let v1 = vec![1,2,3];
    let v2 = [1,2,3];

    println!("{}", v1.into_iter().any(|x| x == 2));
    println!("{}", v2.into_iter().any(|x| *x == 2)); // here x is &integer, so need to use * to deref it
}
Collapse
 
bitecode profile image
BC