翻譯未涵蓋全部內容。完整技術參考請查閱英文原文。 睇英文版 →

模組系統

以明確的引用和命名空間控制將程式碼組織成模組。

模組系統

Sounio 將程式碼組織成模組。一個文件可以通過明確的 module 陳述聲明自己為模組,否則它將留在扁平命名空間內。

聲明模組

// file: ir/profile.sio
module ir::profile

fn sprof_parse(data: &str) -> SprofProfile {
    // ...
}

fn sprof_lookup(profile: &SprofProfile, name: &str) -> i64 {
    // ...
}

module ir::profile 陳述將此文件中的所有定義放在 ir::profile 命名空間下。

從模組中引入

使用 use 將名稱引入作用域:

// 通配符引入 — 將所有公共名稱引入作用域
use ir::profile::*

// 這些函數現在可以直接使用
let profile = sprof_parse(data)
let count = sprof_lookup(profile, "main")

也支援選擇性引入:

use ir::profile::{sprof_parse, sprof_lookup}

重要: 通配符引入 (use module::*) 目前比選擇性引入更可靠,特別是模組內有內部輔助函數時。某些內部輔助函數可能無法通過選擇性引入解決 — 在懷疑時,請使用通配符引入。

扁平命名空間文件

沒有 module 聲明的檔案在扁平命名空間內。它們的定義可以直接對任何能夠看到它們的文件使用,不需要明確的 use 陳述:

// file: ir/normalize.sio
// (no module declaration)

fn normalize_instruction(instr: &!IrInstr) {
    // 其他扁平命名空間文件可以直接使用
}

自托管的編譯器中的 normalize.sio、const_prop.sio、dce.sio 和 ssa.sio 使用這種模式。

模組解決規則

  1. 具有 module X::Y 的檔案必須通過 use X::Y::* 或 use X::Y::{name} 引入。
  2. 沒有 module 的檔案在扁平命名空間內 — 它們的名稱不需要引入即可見。
  3. 前向引用不被支援:輔助函數必須在調用它們的源文件內定義。
  4. 模組路徑映射到文件系統路徑:module ir::profile 對應 ir/profile.sio。

模組和扁平檔案的結合

自托管的編譯器混合使用這兩種模式:

// main.sio — 使用模組和扁平命名空間引入
use ir::ir::*           // 模組引入:IrFunction、IrModule 等。
use ir::profile::*      // 模組引入:SprofProfile、sprof_parse 等。
use ir::inline::*       // 模組引入:inl_run_pass 等。

// normalize.sio、const_prop.sio 是扁平的 — 不需要引入

實用指導

  • 使用 module 為具有明確介面的可重用組件和庫。
  • 使用扁平命名空間為緊密耦合的實現文件,這些文件共享許多內部輔助函數。
  • 當引入 AST 類型時,總是使用 use parser::ast::*(通配符) — 選擇性引入可能會破壞枚舉變體的運算符比較。