理清头脑混沌,觉醒心智天地github
我不太清楚 「Rust 往事」会不会是一个系列,先建个专栏再说。
原本想把 「往事」限定于 1.0 版本以前,但又以为太狭隘了。Rust 是一门不断向前发展的语言,所谓往事,我以为应该是 Rust 在发展过程当中,经历过的全部决策和讨论。

我曾经一直想不明白一个问题:为何下面代码中
while true
没法经过编译 ?
fn main() { let mut a; while true { a = 1; break ; } println!("{}", a); }
而将 while true 换为 loop 则能够经过编译:
fn main() { let mut a; loop { a = 1; break ; } println!("{}", a);}
我清楚它们之间的区别, while true 在编译期静态分析的时候和 loop 不太同样。
前者由于是 while 条件,因此编译器没法在编译期肯定它的值究竟是不是 true,由于 while 表达式的条件位置并不是一个 常量上下文,因此没法在编译期求值,而只能检查类型。
后者则由于是永久循环,必然会执行一次,况且这里又加了 break,因此编译器会在编译期将 a 直接初始化为常量 1。即使这里不加 break,编译器也会进行初始化,大不了加个 goto 指令一直初始化。
以前
const fn
中没法使用 while 也就罢了,如今 1.46 版本中 const fn 增长了对 if/ while 的支持,可为何还不肯意(并不是识别不了)识别 while true 呢?
因而,我翻了一下 Rust 语言源码仓库里的issues,找到一条有意思的 issues #12975:
「Remove `loop` keyword from the language」 ,地址:
https://github.com/rust-lang/rust/issues/12975。
什么状况?从 Rust 中移除 loop 关键字 ?仔细看了一下,才发现是 2014 年的。该 Issues 建议:
移除 loop 关键字,换成 while true。注意,这里是将 while true 总体来替代 loop。由于其余不少语言都是用的 while true ,这里就没必要要加 loop 了。web
while true 能够简化为 while { ... } .sql
这个建议看上去,好像是挺有道理。因而,另一我的就立刻响应,写了一份 RFC:「Propose replacing the `loop` keyword with `while true`」,地址:
https://github.com/rust-lang/rfcs/pull/429
。
这个 RFC 固然没有被经过审核,不然如今就看不到 loop 关键字了,官方团队以「没有兴趣删除 loop 为由,关闭了此 RFC」。看当时 RFC PR 下面的讨论,nrc 其实说了具体的理由:「这种更改,实际上是在区别对待 while <condition == true > 和 while true」,这种设计比较粗鲁。假如 while 后面加了一个被识别为 true 的常量表达式,用不用经过编译?
Rust 语言设计的原则之一,就是高度一致性。这样的设计就搞的很迷。
从如今这个时间节点上回头看,Rust 官方没有接受这个 RFC 是对的。
虽然在编译期识别 true 字面量易如反掌,但总体来看,while true 其实属于一种特殊的状况,更为广泛的是 while (constexpr == true) 的状况,若是后者的条件表达式越复杂越难判断究竟是不是 true。
为了保持语言的一致性,就不能给 while true 开小灶。语言缺少一致性,对于开发者来讲,实际上是一种灾难。
因而 Rust 团队增长了一个 lint :
#[warn(while_true)]
,默认状况下是 warn,但也可使用,#[deny(while_true)] 和 #[allow(while_true)] 。
warning: denote infinite loops with `loop { ... }` |6 | while true { | ^^^^^^^^^^ help: use `loop` | = note: `#[warn(while_true)]` on by default
当你习惯性使用 while true 的时候,Rust 会以警告的方式提示你:无限循环请使用 loop。可是你执意要使用 while true 的话,就最好加上 `#[allow(while_true)]` 。然而,我其实更喜欢用 loop,简单明了。
这其实也算是 Rust 语言设计上的一种妥协吧。缘由有二:
while true 在语义上确实会让人理解为无限循环,没毛病。微信
-
有些人确实喜欢用 while true,你不能不让他用。
像这样经过 lint 的方式来提示开发者也是一种很好的方式,美中不足的是,这个 warning 还缺少一个解释,解释为何 while true 和 loop 的这个区别。这也是为何有这篇文章的缘由。app
从这件小故事中看得出来,Rust 语言团队坚守语言设计原则,才能有如今的 Rust。这样的争论,其实在 Rust 社区发生过很多次,好比稳定异步特性的过程当中,Pin的引入,以及 async/await 语法的设计等等。