Iterating an array with a local mutable copy in Rust

Viewed 384

I am a Rust beginner and could not find anything regarding this in the docs. Would appreciate any help. The following loop in C++

for (const int i : {1,2,3,4,5})
  cout << i;

roughly translates into

for &i in &[1,2,3,4,5] {
    println!("{}", i);
}

Is there a way to write the equivalent of

for (int i : {1,2,3,4,5}) {
  i += 1;
  cout << i;
}

in Rust concisely? Namely is there a shorthand to make a local mutable copy of whats being iterated over?

1 Answers

Yes!

The left part of a for is a pattern.

There are three patterns that you need for this:

  • &pat as you already have, because you get references when iterating.
  • mut name that creates a mutable binding. You are currently using the name pattern, which creates an immutable binding, arguably the simplest of the patterns!
  • (pat) where parenthesis can be used to disambiguate sub-patterns.

Patterns can be combined together which would give:

for &(mut i) in &[1, 2, 3, 4, 5] {
    i += 1;
    println!("{}", i);
}

(Permalink to the playground)

The parenthesis are necessary to disambiguate from another pattern &mut pat which means binding a mutable reference, which isn't the same.

However, I wouldn't say this is very common, and a more common way would be to do this is two steps:

for &i in &[1, 2, 3, 4, 5] {
    let i = i + 1;
    println!("{}", i);
}

or

for &i in &[1, 2, 3, 4, 5] {
    let mut i = i; // rebind as mutable
    i += 1;
    println!("{}", i);
}
Related