Rust中的const常量与static变量

6,495 阅读3分钟

本文首发于我的知乎专栏: zhuanlan.zhihu.com/p/110107918 转载请标注出处

Rust常量(const)

  • 定义如下:

    const NUM:i32=100	
    
  • 定义常量与定义普通变量的区别

    • 关键字是***const***而不是***let***

    • 必须指定变量类型(如***i32***)而不能省略,例如下面这样子是编译不通过的:

      const NUM=100	//Compile Error!
      
    • 定义常量时变量的命名规则一般是全部大写(如***NUM***),非强制,但是会有warning。

    • 常量可以在任意作用域进行定义,而定义的常量贯穿整个程序的生命周期。在编译的时候,编译器会尽可能将其内联到代码中,所以在不同地方对同一常量的引用并不能保证引用到相同的内存地址。

    • 常量的赋值只能是常量表达式/数学表达式,也就是说必须是在编译期就能计算出的值,如果需要在运行时才能得出结果的值比如函数,则不能赋值给常量表达式。

    • 对于变量出现重复的定义(绑定)会发生变量遮盖,后面定义的变量会遮住前面定义的变量,而对于常量则是不允许出现重复的定义的。例如下面的代码就会报错:

      #[test]
      fn test_define_same_const_variable(){
          const NUM:i32=100;
          const NUM:f64=200.0;//error[E0428]: the name `NUM` is defined multiple times
      }
      
      

Rust 全局变量(static)

  • 定义如下
static NUM: i32 = 100;
  • 全局变量和常量类似,但是一个重要的区别就是,全局变量不会被内联,在整个程序中,全局变量只有一个实例,也就是说所有的引用都会指向一个相同的地址。
  • 定义全局变量使用关键字***static***,而定义常量使用***const***,定义普通变量使用***let***
  • 和常量不同,全局变量可以定义为***可变的(mut)***,定义方式如下:
static mut NUM:i32 = 100

因为全局变量可变,就会出被多个线程同时访问的情况,因而引发内存不安全的问题,所以对于全局可变(static mut)变量的访问和修改代码就必须在unsafe块中进行定义,比如这样:

unsafe {
    NUM += 1;
    println!("NUM: {}", NUM);
}
  • 存储在全局(static)变量中的值必须是Sync,也就是需要实现Sync trait.
  • 和常量相同,在定义全局变量的时候必须进行赋值,且赋值必须是在编译期就可以计算出的值(常量表达式/数学表达式),不能是运行时才能计算出的值(如函数)

如何选择使用常量(const)还是全局变量(static)

通常来讲,如果需要在两者之间进行选择,那就选择***常量(const)***,使用全局变量始终在内存中占据一小块地方,但是常量则可以运行编译期进行优化(内联),不仅可以优化自己的crate,而且如果有其他人使用你的crate,也可以进行有欧化。

欢迎关注我的公众号 【Rust碎碎念】

参考链接:

www.twle.cn/c/yufei/rus…

doc.rust-lang.org/1.0.0/book/…