< 返回我的博客

爱国的张浩予 发表于 2021-11-26 00:20

Tags:static,const,let

static, const, let声明变量有什么区别?

就【求值-时间点】来讲,

  • staticconst都是【编译时】求值
  • let是【编译时】绑定,求值时间点取决于赋值语句右侧值的类型
    • 【常量表达式】编译时求值
    • 【普通表达式】运行时求值

就【赋值】来讲,

  • staticconst仅只接受【常量表达式】。
  • const不能引用一个static,但可引用另一个const
  • let既可以接受【常量表达式】,也能够接受运行时求值的普通表达式。

就【内存管理】来讲,

  • const - 其自身不占用任何内存空间。相反,常量值会被直接【内联】入它被使用的(若干)位置。
  • static - 其全局单实例会被保存于【只读】内存区域内。程序各处仅能拿到static单实例的引用。
  • let - 保存变量值于【栈】内存的【帧】中,且随着函数执行结束,而被释放。

Drop trait而言,

  • static - 其生命周期等长于整个应用程序(即,无限生命)。所以,即使static值被实现了Drop trait,它的drop()成员函数也没有机会被调用。
  • constlet都是“有限生命”,超出了作用域都得被释放。若实现了Drop trait,它的drop()成员函数一定会被调用。

就【类型注释】来讲,

  • staticconst都要求Rustacean显示地标注变量的数据类型,不支持类型推断。
  • let支持变量类型推断,数据类型标注项可以被省略。

就【生命周期】来讲,

  • staticconst都要求'static。但根据static lifetime elision规则,生命周期标注可缺省。
  • let没有限制

trait bound而言,

  • static要求静态量必须是Sync trait。即,单实例的引用可在线程间安全地共享。
  • constlet都没有限制。

就【具名】来讲,

  • constlet都被允许声明一个【不具名】常量(即,常量名为_)。我是真不理解这有什么用。
  • static没有这个能力。

就【可修改性】来讲,

  • const门也没有
  • static就得话分两说了:
    • 直接static mut声明可修改变量,会导致unsafe代码。无论读还是写static mut值都是unsafe的。
    • 借助interior Mutability让【编译时】只读的变量在【运行时】可修改,可绕过unsafe约束。但要区分处理单线程RefCell<T>与多线程Mutex<T>的使用场景。
  • letstatic类似,只是let mut声明可修改变量不会导致unsafe代码。

欢迎同学会来留言补充。

评论区

写评论
c5soft 2023-03-17 10:49

好文

ZK645968 2021-11-26 09:51

太强了,大佬真了不起

1 共 2 条评论, 1 页