static
, const
, let
声明变量有什么区别?
就【求值-时间点】来讲,
static
与const
都是【编译时】求值let
是【编译时】绑定,求值时间点取决于赋值语句右侧值的类型- 【常量表达式】编译时求值
- 【普通表达式】运行时求值
就【赋值】来讲,
static
与const
仅只接受【常量表达式】。const
不能引用一个static
,但可引用另一个const
。let
既可以接受【常量表达式】,也能够接受运行时求值的普通表达式。
就【内存管理】来讲,
const
- 其自身不占用任何内存空间。相反,常量值会被直接【内联】入它被使用的(若干)位置。static
- 其全局单实例会被保存于【只读】内存区域内。程序各处仅能拿到static
单实例的引用。let
- 保存变量值于【栈】内存的【帧】中,且随着函数执行结束,而被释放。
就Drop trait
而言,
static
- 其生命周期等长于整个应用程序(即,无限生命)。所以,即使static
值被实现了Drop trait
,它的drop()
成员函数也没有机会被调用。const
与let
都是“有限生命”,超出了作用域都得被释放。若实现了Drop trait
,它的drop()
成员函数一定会被调用。
就【类型注释】来讲,
static
与const
都要求Rustacean
显示地标注变量的数据类型,不支持类型推断。let
支持变量类型推断,数据类型标注项可以被省略。
就【生命周期】来讲,
static
与const
都要求'static
。但根据static lifetime elision
规则,生命周期标注可缺省。let
没有限制
就trait bound
而言,
static
要求静态量必须是Sync trait
。即,单实例的引用可在线程间安全地共享。const
与let
都没有限制。
就【具名】来讲,
const
与let
都被允许声明一个【不具名】常量(即,常量名为_
)。我是真不理解这有什么用。static
没有这个能力。
就【可修改性】来讲,
const
门也没有static
就得话分两说了:- 直接
static mut
声明可修改变量,会导致unsafe
代码。无论读还是写static mut
值都是unsafe
的。 - 借助
interior Mutability
让【编译时】只读的变量在【运行时】可修改,可绕过unsafe
约束。但要区分处理单线程RefCell<T>
与多线程Mutex<T>
的使用场景。
- 直接
let
和static
类似,只是let mut
声明可修改变量不会导致unsafe
代码。
欢迎同学会来留言补充。
1
共 2 条评论, 1 页
评论区
写评论好文
太强了,大佬真了不起