[Rust] 变量的属性: 不可变(immutable), 可变(mutable), 重定义(shadowing), 常量(const), 静态(static)

[Rust] 变量的属性: 不可变(immutable), 可变(mutable), 重定义(shadowing), 常量(const), 静态(static)

变量的可变性

在 Rust 中, 变量可以具有下面的属性。

  • immutable: 不可变变量
  • mutable: 可变变量
  • shadowing: 重定义(遮蔽)一个变量
  • const: 常量
  • static: 静态变量

不可变变量(immutable) vs 可变变量(mut)

Rust 的安全哲学要求变量默认是不可变的。

fn main() {
    // 定义一个不可变的变量
    let x = 5;
    // 错误: cannot assign twice to immutable variable `x`
    // x = 6;

    // 定义一个可变的变量
    let mut y = 5;
    // 正确。可以改变!
    y = y + 1;

    println!("{}", x + y);
}

重定义(shadowing) vs 可变变量(mut)

重定义(遮蔽)特性是一个 Rust 特有的语言特性。
相对于可变变量,重定义(遮蔽)一个变量,可以改变原有变量的数据类型和可变性。

fn main() {
    // 定义一个不可变的变量
    let x = 5;

    // 重定义变量 x。注意:变量类型和可变性都可以变。
    // 变量 x 从整数数据类(i32)型变成了字符串数据类型(String)。
    // 变量 x ,因为声明了 mut ,可变性也变成可变的。
    let mut x: String = (x + 1).to_string();
    // 正确。可以改变!
    x = x + ":1";

    println!("{}", x);
}

重定义特性的其它特点:

  • 重定义特性可以作用于不可变变量
  • 重定义特性可以作用于可变变量
  • 重定义特性不可以作用于 static 变量
  • 重定义特性不可以作用于 const 常量

常量(const)

常量的一个非常重要的特点是: 它的值会在编译时被 copy 到使用的地方。
注意:这种 copy 也会发生在外部包被编译的场合。因此,一定要确保你的常量不会在后续的开发中发生变化。

静态(static)

一个静态变量在应用中拥有唯一的内存地址。
大多数场合,静态变量会被定义为可变的。
在 Rust 的安全哲学中静态变量不是线程安全的,所以可变的静态变量在被读和写的场合,都需要标识 unsafe。

// 定义一个可变的静态变量
static mut LEVEL: i32 = 5;
// 定义一个不可变的静态变量
static CORRECT: i32 = 1;

fn main() {
    // 错误: note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
    LEVEL = LEVEL + 1;
    // 错误: note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
    println!("{}", LEVEL);
    // 正确: 不可变的静态变量是线程安全的。
    println!("{}", CORRECT);

    // 读写静态变量都需要在unsafe中
    unsafe {
        // LEVEL = LEVEL + 1;
        println!("{}", LEVEL);
    }
}

静态(static) vs 常量(const)

那么,什么时候使用静态变量?什么时候使用常量呢?

  • 数据占有内存比较大的场合,使用静态变量;
  • 程序需要变量的地址属性的情况下,使用静态变量;
  • 变量需要是可变的情况下,使用静态变量;
  • 其它场合,推荐使用常量;

参照

posted @ 2021-03-31 10:31  SNYang  阅读(695)  评论(0编辑  收藏  举报