理清頭腦混沌,覺醒心智天地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 語法的設計等等。