当未声明为变量的变量被修改时,为什么编译器不报告错误?

Tro*_*yvs 8 variables syntax compilation mutable rust

我安装了Rust 1.13并试过:

fn main() {
    let x: u32;
    x = 10; // no error?
}
Run Code Online (Sandbox Code Playgroud)

当我编译这个文件时有一些警告,但是没有错误.因为我不声明x作为mut,不应该x = 10;导致错误?

Pet*_*all 15

你写的内容与:

let x: u32 = 10;
Run Code Online (Sandbox Code Playgroud)

之后编译器不允许您进行变更:

let x: u32;
x = 10;
x = 0; // Error: re-assignment of immutable variable `x`
Run Code Online (Sandbox Code Playgroud)

请注意,如果您尝试使用未初始化的变量,则编译器错误:

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

如果要根据运行时条件以不同方式初始化变量,此功能非常有用.一个天真的例子:

let x: u32;
if condition {
    x = 1;   
} else if other_condition {
    x = 10;
} else {
    x = 100;
}
Run Code Online (Sandbox Code Playgroud)

但如果有可能它没有被初始化,它仍然是一个错误:

let x: u32;
if condition {
    x = 1;   
} else if other_condition {
    x = 10;
} // no else
println!("{:?}", x); // Error: use of possibly uninitialized variable: `x`
Run Code Online (Sandbox Code Playgroud)

  • 惯用生锈更可能在这里使用面向表达式的语法:`let x = if condition {1} else if else_condition {10} else {100};`.在这些示例中不需要延迟初始化. (7认同)

Mat*_* M. 11

如上所述,这不是变异,而是延迟初始化:

  • 变异是关于改变现有变量的值,
  • 延迟初始化是关于在一个点声明一个变量,并在以后初始化它.

Rust编译器跟踪变量在编译时是否具有值,因此与C不同,不存在意外使用未初始化变量的风险(或者与C++(从中移动的变量)不同.


使用延迟初始化的最重要原因是范围.

fn main() {
    let x;
    let mut v = vec!();

    {
        x = 2;
        v.push(&x);
    }

    println!("{:?}", v);
}
Run Code Online (Sandbox Code Playgroud)

在Rust中,借用检查器将验证引用不能超过它引用的值,从而防止悬空引用.

这意味着v.push(&x)要求x寿命超过v,因此要在之前 宣布v.

对它的需求并不经常出现,但是当它做其他解决方案时需要运行时检查.