Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Does the `map` call serve any purpose here?

Code:

pub fn iter(&self) -> impl Iterator<Item = (&usize, &T)> + '_ {
    self.values.iter().map(|(key, value)| (key, value))
}

Quoted from here, it seems following is enough:

pub fn iter(&self) -> impl Iterator<Item = (&usize, &T)> + '_ {
    self.values.iter()
}

Any difference?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Yes, the former returns a type that implements Iterator<Item = (&usize, &T)> + '_ while the latter returns a type that implements Iterator<Item = &(usize, T)> + '_.

Here a minimal example:

pub fn iter1(v: &[(usize, i32)]) -> impl Iterator<Item = (&usize, &i32)> + '_ {
    v.iter().map(|(key, value)| (key, value))
}

pub fn iter2(v: &[(usize, i32)]) -> impl Iterator<Item = (&usize, &i32)> + '_ {
    v.iter()
}

fails to compile with this error message:

error[E0271]: expected `std::slice::Iter<'_, (usize, i32)>` to be an iterator that yields `(&usize, &i32)`, but it yields `&(usize, i32)`
 --> src/lib.rs:5:37
  |
5 | pub fn iter2(v: &[(usize, i32)]) -> impl Iterator<Item = (&usize, &i32)> + '_ {
  |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&(usize, i32)`, found tuple
6 |     v.iter()
  |     -------- return type was inferred to be `std::slice::Iter<'_, (usize, i32)>` here
  |
  = note: expected reference `&(usize, i32)`
                 found tuple `(&usize, &i32)`

For more information about this error, try `rustc --explain E0271`.
error: could not compile `playground` due to previous error

Playground.

The former works thanks to ergonomics build into Rust’s pattern syntax called binding modes:

When a reference value is matched by a non-reference pattern, it will be automatically treated as a ref or ref mut binding.

So it is basically syntactic sugar for v.iter().map(|&(ref key, ref value)| (key, value)), which makes it clearer why the former works, but the latter doesn’t.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading