附錄 G - Rust 的開發流程與「每夜版 Rust」

本附錄會介紹 Rust 是如何開發的,以及這對身為 Rust 開發者的你會有何影響。

無停滯穩定

身為一門語言,Rust 十分注重程式碼穩定性。我們希望 Rust 成為你在開發中的穩固基石,如果經常在更新的話,這樣的願望就很難達成了。同時,如果我們不能實驗新功能的話,直到它們發佈之前,我們可能就無法找出重大瑕疵,而且發佈後我們就很難再加以更改了。

我們對此問題的解決方案為「無停滯穩定(stability without stagnation)」,而我們的指導原則為:你永遠不該害怕升級最新的 Rust 穩定版。每次都該是無痛升級,但同時也該提供新功能、修正錯誤並加快編譯時間。

嘟嘟火車出發!發佈通道與時刻表

Rust 開發團隊有個發佈時刻表(train schedule)。而所有的開發工作都在 Rust repository 的 master 分支上。發佈採用軟體發佈火車模型(software release train model),這也被用於 Cisco IOS 與其他的軟體專案。Rust 有三個發佈通道(release channels)

  • 每夜版(Nightly)
  • 測試版(Beta)
  • 穩定版(Stable)

大多數的 Rust 開發者主要都使用穩定版的通道,但是想要實驗新功能的人可以嘗試使用每夜版或測試版。

以下是開發與發佈過程是如何進行的範例:讓我們假設 Rust 團隊正在準備發佈 Rust 1.5。這版本在 2015 年十二月就發佈,做此假設只是為我們提供較真實的版本數字。其中有一個新功能會加入 Rust 並在 master 分支新增一個 commit。每個晚上 Rust 都會產生新的每夜版版本,然後每到天亮就會發佈,而這些發佈均由發佈基礎設施自動產生。所以隨著時間過去,我們每晚都會有一個發佈像這樣進行:

nightly: * - - * - - *

接著每隔六週就是時候發佈新的發佈版本了!Rust repository 的 beta 分支會從每夜版使用的 master 分支產生。現在我們就有了兩種發佈:

nightly: * - - * - - *
                     |
beta:                *

大多數的 Rust 使用者並不會直接使用測試版發佈,而會用他們的 CI 系統來檢查測試版來幫助 Rust 發現可能的迴歸錯誤(regressions)。同時,每夜版仍然會每晚產生新的發佈:

nightly: * - - * - - * - - * - - *
                     |
beta:                *

假設有迴歸錯誤被發現了,那這對我們來說就是個好消息。因為在錯誤潛入穩定版發佈之前,我們還有些時間能檢測測試版的發佈!修正會加到 master,所以每夜版就能被修正。然後該修正也會合併到 beta,所以新的測試版發佈就會跟著產生:

nightly: * - - * - - * - - * - - * - - *
                     |
beta:                * - - - - - - - - *

再經過第一個測試版產生的六週後,就是時候發佈穩定版了!stable 分支會從 beta 分支中產生:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |
beta:                * - - - - - - - - *
                                       |
stable:                                *

太好了!Rust 1.5 終於釋出了!不過我們不能忘記一件事,由於六週過去了,我們也必須為下一個 Rust 1.6 版本準備新的測試版。所以在 stablebeta 產生後,下個版本的 beta 分支會再次從 nightly 產生:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |                         |
beta:                * - - - - - - - - *       *
                                       |
stable:                                *

這就叫「火車模型(train model)」,因為每隔六週就會有個發佈「駛離車站」,但其仍需要穿梭過測試版通道,才能抵達穩定版發佈。

Rust 會像發條裝置一樣每隔六週定時發佈。如果你已經知道一個 Rust 發佈的日期,你就能知道下一個的發佈日期,也就是六週之後。這樣每隔六週發佈的時程表有個好處是下一輛火車很快也會接著抵達。如果某個特定版本遺漏某項功能的話,不用擔心,因為下一版很快就會來臨了!這能降低發佈截止日期前,不得不偷偷釋出尚未完善的功能的壓力。

幸虧有此流程,你永遠都可以看到 Rust 的下一個版本並驗證你是否能輕鬆升級。如果測試版不如你所預期,你可以回報給團隊並在穩定版發佈前修正完成!在測試版出現重大缺陷是很少見的,但 rustc 本身仍是個軟體,總避免不了些錯誤發生。

不穩定功能

此發佈模型還有一項重點,那就是不穩定(unstable)功能。Rust 使用一個叫做「功能標記(feature flags)」的技術來決定一個發佈能啟用哪些功能。如果有個新功能正在積極開發中,它可以加進 master 因而出現在每夜版中,但是會有個功能標記。如果身為使用者的你想要嘗試看看仍在開發中的功能的話,你是可以使用的。但是你必須透過 Rust 每夜版並在你的程式碼指明對應的功能標記才行。

如果你使用的是測試版或穩定版 Rust,你就無法使用任何功能標記。這是讓我們在宣佈新功能已經永遠穩定前,能夠確實測試它們的關鍵。這滿足了想使用前沿技術的人,同時也確保維持在穩定版的人有穩固的基石,不會讓他們的程式碼被破壞。這就是所謂的無停滯穩定。

本書只涵蓋了穩定版的功能資訊,因為開發中的功能可能隨時會改變。當其納入穩定版時肯定會與此書撰寫的時候而有所不同。你可以在線上找到每夜版功能的技術文件。

Rustup 與 Rust 每夜版的職責

Rustup 能夠輕鬆切換不同的 Rust 發佈通道,在全域或是每個專案的範圍都行。而預設情況下,你會安裝穩定版 Rust。要安裝每夜版的話,請輸入以下命令:

$ rustup toolchain install nightly

你還可以看到你透過 rustup 安裝的所有工具鏈(toolchains)(Rust 的發佈與相關元件)。以下是本書其中一位作者 Windows 電腦中的範例:

> rustup toolchain list
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc

如你所見,穩定版工具鏈是預設選項。大多數 Rust 使用者在大部分時間都會使用穩定版。你可以平時在大部分時間使用穩定版,並在需要使用前沿技術功能的特定專案下使用每夜版。為此,你可以在該專案目錄下使用 rustup override 來設置 rustup 在該目錄下需要使用每夜版工具鏈:

$ cd ~/projects/needs-nightly
$ rustup override set nightly

現在你每次在 ~/projects/needs-nightly 底下呼叫 rustccargo 的話,rustup 會確保你使用的是每夜版 Rust,而不是預設的穩定版 Rust。這在當你有一堆 Rust 專案時會非常好用!

RFC 流程與團隊

所以你該怎麼學習這些新功能呢?Rust 的開發模型遵循的是請求意見稿(Request For Comments, RFC)流程。如果你想要改善 Rust,你可以寫篇 RFC 提案。

任何人都可以寫篇 RFC 來改善 Rust,然後該提案會經由 Rust 團隊審核並討論,而團隊有許多子主題團隊所組成。在 Rust 官網上有完整的團隊列表,包含每個專案領域的團隊,像是語言設計、編譯器實作、基礎設施、技術文件以及更多等等。相對應的團隊會閱讀提案並留言、寫些他們的想法,並在最後達成共識,決定要接受或拒絕該功能。

如果功能被接受了,Rust repository 便會開啟對應 issue,然後每個人就都能嘗試實作它。實作該功能的人很可能與當初提案的人不相同!當實作準備好後,它便會加入 master 分支並有個功能標記,如同我們在「不穩定功能」段落所提及的。

經過一段時間後,一旦使用每夜版發佈的 Rust 開發者嘗試過新功能後,團隊成員會討論此功能,其在每夜版運行的如何,並決定它是否該加到穩定版。如果決定進一步加入的話,功能標記就會被移除,然後該功能就會是穩定功能了!它就像搭乘火車班抵達最新的 Rust 穩定版發佈。