Why doesn't the compiler report an error when a variable not declared as mutable is modified?

前端 未结 2 1408
后悔当初
后悔当初 2020-12-20 17:56

I installed Rust 1.13 and tried:

fn main() {
    let x: u32;
    x = 10; // no error?
}

When I compiled this file there\'s some warnings, b

相关标签:
2条回答
  • 2020-12-20 18:08

    As mentioned, this is not mutation, but deferred initialization:

    • mutation is about changing the value of an existing variable,
    • deferred initialization is about declaring a variable at one point, and initializing it later.

    The Rust compiler tracks whether a variable has a value at compile-time, so unlike C there is no risk of accidentally using an uninitialized variable (or unlike C++, a variable that was moved from).


    The most important reason for using deferred initialization is scope.

    fn main() {
        let x;
        let mut v = vec!();
    
        {
            x = 2;
            v.push(&x);
        }
    
        println!("{:?}", v);
    }
    

    In Rust, the borrow-checker will validate that a reference cannot outlive the value it refers to, preventing dangling references.

    This means that v.push(&x) requires that x lives longer than v, and therefore be declared before v.

    The need for it does not crop up often, but when it does other solutions would require run-time checks.

    0 讨论(0)
  • 2020-12-20 18:22

    What you have written is identical to:

    let x: u32 = 10;
    

    The compiler will not permit you to mutate it thereafter:

    let x: u32;
    x = 10;
    x = 0; // Error: re-assignment of immutable variable `x`
    

    Note that it is a compiler error if you try to use an uninitialized variable:

    let x: u32;
    println!("{}", x); // Error: use of possibly uninitialized variable: `x`
    

    This feature can be pretty useful if you want to initialize the variable differently based on runtime conditions. A naive example:

    let x: u32;
    if condition {
        x = 1;   
    } else if other_condition {
        x = 10;
    } else {
        x = 100;
    }
    

    But still it will still be an error if there is a possibility that it isn't initialized:

    let x: u32;
    if condition {
        x = 1;   
    } else if other_condition {
        x = 10;
    } // no else
    println!("{:?}", x); // Error: use of possibly uninitialized variable: `x`
    
    0 讨论(0)
提交回复
热议问题