前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Rust 变量默认不可变的设计到底是为了什么

Rust 变量默认不可变的设计到底是为了什么

作者头像
睡觉谁叫
发布2023-05-01 16:10:06
4090
发布2023-05-01 16:10:06
举报
文章被收录于专栏:Flutter性能监控Flutter性能监控
highlight: a11y-light theme: condensed-night-purple

问题详述

为什么 Rust 里的变量被设计成默认不可变,要加mut关键词才可变?为什么不设计成默认可变,加关键词变成不可变? 或者两者同等地位,比如像某语言一样let不可变,var可变?

观点一:

默认设计成不可变没啥特别原因,但是可以聚焦到 rust 的基本特性:安全性。从这个方面考虑。如果忘记设置 mut,编译器会捕捉到错误,并让你知道你已经改变了一些你可能不打算改变的东西。如果默认情况下绑定是可变的,编译器将无法告诉你这一点。若你确实打算改变,那么解决方案很简单:添加mut

通常情况下,你可以经常避免显示可变,在 Rust 中这是更可取的,话虽然如此,有时候可变是必要的,所以并不禁止。

Shadowing 不同于将变量标记为 mut,因为如果我们在不使用 let 关键字的情况下不小心尝试重新分配给该变量,则会出现编译时错误。通过使用 let,我们可以对一个值执行一些转换,但在这些转换完成后变量是不可变的。

观点二:

鉴于一种语言具有可变和不可变变量,对我来说默认情况下不可变似乎更好。因为:

当我们谈论语言默认情况时,其实是在说 当你忘记或者懒得在声明变量时指定可变性,将会发生什么? 有两种情况:

  1. 默认情况下可变。经常会发生这种情况,未来项目不止你一个人修改,当修改 bug,增加需求或者重构时。可能不熟悉项目的程序员无意中修改一个变量,修改前他没有意识到该变量是不可变的,进而导致重大事故。偶现事件也很难调试,这是很糟糕的一件事。任何使用过 C/C++等语言在大型代码库和团队中工作的人都遇到过这类问题。
  2. 默认不可变。那将来程序员犯了同样错误。编译阶段编译器就指出来问题,错误将被避免。

当然,未来的程序员可能是你本人,在几个月或者几年后你忘记项目的所有细节,当编译器捕获到错误时你会很开心。

不确定:可能默认情况下不可变的话允许优化,反之则不允许。默认情况下不可变可能带来性能提升。

我怀疑微软有足够的证据表明默认情况下不可变是更好的选择:他们估计 70% 的安全问题都可追溯到此类内存滥用错误:我们需要一种更安全的系统编程语言——微软安全响应中心

简而言之,打个比方,当我出门并打算关闭身后前门时,我更愿意默认情况下它是自动关上了。

观点三:

rust 允许 variable shadowing,所以下面这种写法是完全有可能的。

代码语言:javascript
复制
let a = 0u8;
let mut a = a;
a = 1;
let a = a;

用 rust-analyzer 辅助可以看出一个变量有没有被 shadowing 过,但是靠肉眼判断应该是不太行的。

除了 shadowing,还有 interior mutability……感觉 rust 的默认不可变是一种非常宽松的约束,只是类似于提醒、建议的程度,很容易绕开。

总结

Rust 变量默认不可变的设计本意是想将可能出现的错误扼杀在摇篮中(编译器行为),类似提醒和告警等。如果你非要绕还是可以绕过去滴。再完备的法典,不还是有人可以钻到空子么?法律只是最低的道德标准,语言设计理念亦然。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题详述
  • 观点一:
  • 观点二:
  • 观点三:
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档