Search code examples
rustpass-by-referencemutable

How to make a mutable reference to an immutable value


I'm just beginning to learn a little Rust and am very intrigued by the concept of mutability of variables.

I'm trying to write something very similar to this C++ program.

#include <cstdio>

void do_something(int &var) {
   var++;
}

int main() {

    int a = 3;
    int b = a;
    printf("a is %d and b is %d\n", a, b);
    do_something(b);
    printf("a is %d and b is %d\n", a, b);

    return 0;
}

I expect to see:

a is 3 and b is 3

a is 3 and b is 4

The idea is that the pass-by-reference renders b mutable, but a is not mutable.

Here's how I would assume to write this program in Rust:

fn main() {
    let a: i32 = 3;
    let b: &mut i32 = &a;

    println!("a is {} and b is {}", a, b);
    do_something(b);
    println!("a is {} and b is {}", a, b);
}

fn do_something(var: &mut i32) {
    (*var)+=1;
}

However, I get errors due to mismatched mutability.

error: mismatched types:

expected &mut i32, found &i32

(values differ in mutability) [E0308]

Are there ways to secure this pass-by-reference style in Rust without ::New? My guess is I could use .clone(), but I'm not positive.


Solution

  • You’re misunderstanding what the code is doing. Here is the actual equivalent code:

    fn main() {
        let a: i32 = 3;
        let mut b = a;
    
        println!("a is {} and b is {}", a, b);
        do_something(&mut b);
        println!("a is {} and b is {}", a, b);
    }
    
    fn do_something(var: &mut i32) {
        *var += 1;
    }
    

    b is not, in your C code, a reference of any form; it has absolutely no connection with a. It’s just that C allows you to pass a value and have it infer that it must take a reference to it, while Rust is very sensibly explicit about such things, and so you need to write &mut b rather than just b to pass a mutable reference to do_something. The mut b earlier on just makes the b slot mutable, allowing you to mutate the value inside it (without it, you won’t be able to create a mutable reference to b).