透過套件、Crate 與模組管理成長中的專案

當你寫的程式規模更大時,組織你的程式碼就很重要。因為用你的腦袋要記住整個程式碼是幾乎不可能的。要是能組織相關功能的程式碼並將它們分成明確功能的話,你就能清楚地找到實作特定功能的程式碼,以及該在哪裏修改該功能的行為。

我們之前寫過的程式都只在一個檔案內的一個模組(module)中。隨著專案成長,我們可以組織程式碼,拆成數個模組與數個檔案。一個套件(package)可以包含數個二進制 crate 以及選擇性提供一個函式庫 crate。隨著套件增長,你可以取出不同的部分作為獨立的 crate,成為對外的依賴函式庫。此章節將會介紹這些所有概念。對於非常龐大的專案,需要一系列的關聯套件組合在一起的話,Cargo 有提供工作空間(workspaces),我們會在第十四章的「Cargo 工作空間」做介紹。

除了為了組織功能以外,對實作細節進行封裝可以讓你的程式碼在頂層更好使用。一旦你實作了某項功能,其他程式就可以用程式碼的公開介面呼叫該程式碼,而不必去知道它實作如何運作。你在寫程式碼時會去定義哪些部分是給其他程式碼公開使用的,以及哪些部分是私底下你可以任意修改的實作細節。這能再減少你的腦袋需要煩惱的細節數量。

還有一個概念需要再提一次,也就是作用域(scope):程式碼需要能被定義在「作用域內」並要能夠指明此作用域。當讀取寫入或編譯程式碼時,程式設計師與編譯器需要知道特定地點的名稱,才能知道其內的變數、函式、結構體、枚舉、常數或其他任何有意義的項目。你可以建立作用域,並改變其在作用域內與作用域外的名稱。你無法在同個作用域內擁有兩個相同名稱的項目。我們可以使用一些工具來解決名稱衝突的問題。

Rust 有一系列的功能能讓你管理你的程式碼組織,包含哪些細節能對外提供、哪些細節是私有的,以及程式中每個作用域的名稱為何。這些功能有時會統一稱作模組系統(module system),其中包含:

  • 套件(Package): 讓你建構、測試並分享 crate 的 Cargo 功能
  • Crates: 產生函式庫或執行檔的模組集合
  • 模組(Modules)use: 讓你控制組織、作用域與路徑的隱私權
  • 路徑(Paths): 對一個項目的命名方式,像是一個結構體、函式或模組

在本章節中,我們會涵蓋所有這些功能,討論它們如何互動,並解釋如何使用它們來管理作用域。在讀完後,你應該就會對模組系統有紮實的認知,並能夠對作用域的使用駕輕就熟!