Rust 变量和可变性

在默认情况下rust变量是不可变的。这样可以使代码更加安全。让我们探讨一下Rust如何以及为什么鼓励您支持变量不可变,以及为什么有时您可以选择可变变量。

声明变量

通过let关键字声明变量,可以不声明变量类型,交由编译器判断。

let spaces = "";

也可以声明变量类型:

let spaces:&str = "";

不可变变量

以下代码为错误代码:

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

以下为错误信息:

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:5
  |
2 |     let x = 5;
  |         -
  |         |
  |         first assignment to `x`
  |         help: make this binding mutable: `mut x`
3 |     println!("The value of x is: {}", x);
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0384`.
error: could not compile `variables`.

To learn more, run the command again with --verbose.

错误消息表明错误的原因是cannot assign twice to immutable variable x,因为您试图为不可变变量x分配第二个值。尝试更改以前指定为不可变的变量时,将会抛出编译时错误。

如此设计的原因:
如果我们的代码的一部分在假设值永远不会改变的情况下运行,而我们代码的另一部分则在改变该值,那么代码的第一部分可能不会按照设计的意图进行操作。实际上,这类错误的原因可能很难追查,尤其是在第二段代码有时仅更改值时。

可变变量

在很多时候可变变量是必要的。我们可以通过添加mut关键字使变量可变。

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

常量

常量与不可变变量有些相似,但是有区别。

  1. 不允许使用mut常量。常量在默认情况下不仅是不可变的,还总是不可变的。
  2. 声明常量使用const关键字,并且必须声明常量类型。
const MAX_POINTS: u32 = 100_000;
  1. 常量可以在任何范围内声明,包括全局范围,这使它们对于许多代码部分需要知道的值很有用。
  2. 常量只能设置为常量表达式,而不能设置为函数调用的结果或只能在运行时计算的任何其他值。

遮蔽(Shadowing)

您可以声明一个与先前变量同名的新变量,并且该新变量会覆盖先前的变量。使用let关键字。

fn main() {
    let x = 5;

    let x = x + 1;

    let x = x * 2;

    println!("The value of x is: {}", x);
}

结果是12。

遮蔽(Shadowing)不同于将变量标记为mut,遮蔽(Shadowing)后的变量依旧是不可变的。

遮蔽(Shadowing)可以使变量类型改变。因为当我们let再次使用关键字时,我们正在有效地创建一个新变量,因此我们可以更改值的类型,重复使用相同的名称。

fn main() {
    let spaces = "   ";
    let spaces = spaces.len();
}

在这里插入图片描述
可以看到原先变量为&str,后变为usize类型。

使用mut则不能改变变量类型,以下为错误代码:

fn main() {
    let mut spaces = "   ";
    spaces = spaces.len();
}

错误提示:

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
 --> src/main.rs:3:14
  |
3 |     spaces = spaces.len();
  |              ^^^^^^^^^^^^ expected `&str`, found `usize`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables`.

To learn more, run the command again with --verbose.

注释 编译器会忽略的常规注释: //注释一整行/* 注释一块 */ 第二类是文档注释,用于通过工具生成HTML API文档 /// 注释一整行//! 这是//! 一个//! 文档注释块 格式化输出 format ...