Immutable

By default rust variables are immutable. Once a value is bound to a name, you can’t change that value. We can make a mutable variable using the keyword mut.

fn main() {
    let mut x = 5;
    println!("The value of x is: {x}");
    x = 6;
    println!("The value of x is: {x}");
}
The value of x is: 5
The value of x is: 6

Constant.

Like immutable variables, constants are values that are bound to a name and are not allowed to change, but there are a few differences between constants and variables. First, you aren’t allowed to use mut with constants. Constants aren’t just immutable by default—they’re always immutable. You declare constants using the const keyword instead of the let keyword, and the type of the value must be annotated. We’ll cover types and type annotations in the next section, “Data Types”, so don’t worry about the details right now. Just know that you must always annotate the type.

const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
println!("{}", THREE_HOURS_IN_SECONDS)
10800

Shadowing

You can declare a new variable with the same name as a previous variable. This means that the first variable is shadowed by the second, which means that the second variable is what the compiler will see when you use the name of the variable.

In effect, the second variable overshadows the first, taking any uses of the variable name to itself until either it itself is shadowed or the scope ends. We can shadow a variable by using the same variable’s name and repeating the use of the let keyword as follows:

fn main() {
    let x = 5;

    let x = x + 1;

    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {x}");
    }

    println!("The value of x is: {x}");
}
The value of x in the inner scope is: 12
The value of x is: 6

This program first binds x to a value of 5. Then it creates a new variable x by repeating let x, taking the original value and adding 1 so the value of x is then 6. Then, within an inner scope created with the curly brackets, the third let statement also shadows x and creates a new variable, multiplying the previous value by 2 to give x a value of 12.

Shadowing is different from marking a variable as mut because we’ll get a compile-time error if we accidentally try to reassign to this variable without using the let keyword. By using let, we can perform a few transformations on a value but have the variable be immutable after those transformations have been completed.