Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this variable need to be mutable?

Tags:

rust

In this code snippet I declared the variable max as mut, but rust-analyer told me that it is not necessary. I removed the mut and the code still works and runs. Why is that? I am reassigning the value for max in the match statement.

fn validate_in_range_u32(value:u32, min:u32, max:u32) -> bool { 
    if value < min || value > max {
        return false;
    }
    true
}

fn main() { 
    let day = 24;
    let month = 8;

    if !validate_in_range_u32(month, 1, 12) {
        println!("Month is out of range (1-12)");
    }
    let max: u32;
    match month {
        1 | 3 | 5 | 7 | 8 | 10 | 12 => max = 31,
        2 => max = 28,
        4 | 6 | 9 | 11 => max = 30,
        _ => panic!("Should not happen"),
    }

    if !validate_in_range_u32(day, 1, max) {
        println!("Day is out of range (1-{max})");
    }
    
    println!("It worked!");
}
like image 983
HWilmer Avatar asked Oct 11 '25 16:10

HWilmer


1 Answers

Why is that? I am reassigning in the match statement the value for max.

You're not actually re-assigning, you're just assigning.

Rust does not do implicit default initialisation, and it tracks "place state", so after

let max: u32;

max is defined but uninitialised, if you try to read it, you will get a compilation error:

error[E0381]: used binding `max` is possibly-uninitialized

So the match statement just initialises it, which Rust doesn't require mutations for.

Incidentally, like most things in rust match are expressions, so a more rust-y style would be to return the values from the match and initialise max in-place:

    let max = match month {
        1 | 3 | 5 | 7 | 8 | 10 | 12 =>31,
        2 => 28,
        4 | 6 | 9 | 11 => 30,
        _ => panic!("Should not happen"),
    };

The type annotation is not necessary either because validate_in_range_u32 imposes u32.

like image 115
Masklinn Avatar answered Oct 15 '25 10:10

Masklinn