常量

看例子

// 全局作用域声明  本课程来自 Foxdevelop.com
static LANGUAGE: &str = "Rust";
const THRESHOLD: i32 = 10;

fn is_big(n: i32) -> bool {
    n > THRESHOLD
}

fn main() {
    let n = 16;

    println!("This is {}", LANGUAGE);
    println!("The threshold is {}", THRESHOLD);
    println!("{} is {}", n, if is_big(n) { "big" } else { "small" });

    // THRESHOLD = 5; // 编译报错,const 不可赋值修改
}Code language: Rust (rust)

输出结果

This is Rust
The threshold is 10
16 is big

2个常量关键字

const

  • 编译期常量
  • 编译时直接内联展开,不存在内存地址;
  • 每次使用相当于字面量复制 永远不可变
  • 必须显式标注类型
  • 可以在任意作用域(全局、函数内部)定义
const MAX: u32 = 100;Code language: Rust (rust)

static

  • 静态变量,拥有 'static 生命周期
  • 在程序数据段分配一块固定内存,所有引用指向同一块地址
  • 支持 static mut 可变静态变量
  • 访问 / 修改 static mut必须包裹在 unsafe(表示线程不安全)
static MSG: &str = "hello";
static mut COUNTER: i32 = 0;Code language: Rust (rust)

对比

特性conststatic
内存模型编译内联,无独立地址程序内存中独占一块地址
是否允许 mut不支持static mut(unsafe)
取值方式字面量拷贝引用同一个内存地址
生命周期无(编译期替换)'static
地址 &每次取地址可能得到不同临时地址永远同一个地址
使用场景固定数值、配置常量全局共享数据、静态资源

地址差异

const C: i32 = 10;
static S: i32 = 10;

fn main() {
    println!("const addr: {:p}", &C);
    println!("const addr: {:p}", &C); // 两次地址不一样!
    println!("static addr: {:p}", &S);
    println!("static addr: {:p}", &S); // 地址完全相同
}Code language: Rust (rust)
const addr: 0x7ff7ed138354
const addr: 0x7ff7ed138354
static addr: 0x7ff7ed138350
static addr: 0x7ff7ed138350Code language: JavaScript (javascript)

static mut(unsafe)

static mut 极容易引发数据竞争,多线程环境尽量避免,优先使用 Mutex 包装

mut 就是 mutable的意思,代表「可变」,允许后续重新赋值、修改;没有 mut 就是 immutable 不可变。

let a = 10;
a = 20; //  报错,没有mut,不可修改

let mut b = 10;
b = 20; //  合法,mut可变变量Code language: Rust (rust)

例子

static mut COUNT: i32 = 0;

fn main() {
    unsafe {
        COUNT += 1;
        let val = COUNT; // 把数值拷贝到局部变量 直接访问Count会报错
        println!("count = {}", val);
    }
}

 //println!("count = {}", COUNT);
 //|                                ^^^^^ shared reference to mutable staticCode language: JavaScript (javascript)

输出

count = 1

总结

  • 单纯固定数字、字符串配置 则 优先 const
  • 需要全局唯一地址、静态资源、外部 FFI 交互 则 使用 static
  • 需要全局可变数据:尽量 static Mutex<T>,不要直接 static mut

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注