几乎每门编程语言都有 const (常量)、static(静态)、inline(内联) 的概念,之前我在:
使用 Clang 深入分析 C 内存从汇编和二进制层面对这些概念进行过深入分析;这里再简单介绍一下,Rust 语言的这些概念和 C 类似。
const 和 static 都是全局定义,意思是在整个程序运行过程中,这些值都会存在;且都存储在全局数据段(通常是 data 段)。const 在 data 段的 readonly 段中,所以 const 定义的都是常量,无法更改。此外 const 定义的值,都是内联展开的。如果在生成环境中,使用编译优化参数,const 的存储可能都被优化掉,都被替换为立即数,这样来看,const 可以看做为寄存器宏定义。
inline
内联,是一个很重要的概念,一般来讲,编程语言对一个变量的定义,底层都会有个符号:
let a = 10; // 伪汇编: Text 0x0000** push @a-exp ; #@a-exp // 伪汇编: Data 0x4000** @a-exp 10;
上边的伪汇编是我自己写的,只为说明原理。
@a-exp
就是 a 变量的符号,运行时根据符号找到具体的值。这样的问题是回额外增加一次寻值操作,inline 的目标就是把这次根据符号寻值优化掉:
let inline a = 10; // 伪汇编: Text 0x0000** push 10;
a 会直接被一个立即数 10 替换,运行时不需要额外开销去寻值。const 就自带这样的特性,Rust 中的 const 定义的值类型,都会被内联展开为立即数。
总结:
- const 是内联的,static 不是内联的。即 static 变量在代码中实际是个内存地址或者符号。
- static 多线程访问的时候,需要互斥锁。
- 由于 const 是内联的,所以编译后其实不存在这个量了,都变成了代码中实际的值。
- const 不可变,static 是可变的。