chapman
chapman

Reputation: 929

How do I pass an array to a function in Rust and change its content?

I want to pass an array to a function and change the content inside it:

fn change_value(mut arr: &[i32]) {
    arr[1] = 10;
}

fn main() {
    let mut arr: [i32; 4] = [1, 2, 3, 4];
    change_value(&arr);
    println!("this is {}", arr[1]);
}

I'm getting this error:

warning: variable does not need to be mutable
 --> src/main.rs:2:17
  |
2 | fn change_value(mut arr: &[i32]) {
  |                 ----^^^
  |                 |
  |                 help: remove this `mut`
  |
  = note: `#[warn(unused_mut)]` on by default

error[E0594]: cannot assign to `arr[_]` which is behind a `&` reference
 --> src/main.rs:3:5
  |
2 | fn change_value(mut arr: &[i32]) {
  |                          ------ help: consider changing this to be a mutable reference: `&mut [i32]`
3 |     arr[1] = 10;
  |     ^^^^^^^^^^^ `arr` is a `&` reference, so the data it refers to cannot be written

warning: variable does not need to be mutable
 --> src/main.rs:7:9
  |
7 |     let mut arr: [i32; 4] = [1, 2, 3, 4];
  |         ----^^^
  |         |
  |         help: remove this `mut`

I've been searching around, but I can't find anything.

Upvotes: 59

Views: 75665

Answers (1)

Vladimir Matveev
Vladimir Matveev

Reputation: 128051

Rust references (denoted by the & sign) are of two kinds: immutable (&T) and mutable (&mut T). In order to change the value behind the reference, this reference has to be mutable, so you need to:

  1. accept &mut [i32] as the function argument, not &[i32]
  2. pass &mut arr to the function, not &arr:
fn change_value(arr: &mut [i32]) {
    arr[1] = 10;
}

fn main() {
    let mut arr: [i32; 4] = [1, 2, 3, 4];
    change_value(&mut arr);
    println!("this is {}", arr[1]);
}

You don't need mut arr in change_value's argument because mut there denotes mutability of that variable, not of the data it points to. With mut arr: &[i32] you can reassign arr itself (for it to point to a different slice), but you can't change the data it references.

If you wanted to accept an array instead of a slice, you could also do that:

fn change_value(arr: &mut [i32; 4]) {
    arr[1] = 10;
}

See also:

Upvotes: 88

Related Questions