模組系統
以明確的引用和命名空間控制將程式碼組織成模組。
模組系統
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 使用這種模式。
模組解決規則
- 具有
module X::Y的檔案必須通過use X::Y::*或use X::Y::{name}引入。 - 沒有
module的檔案在扁平命名空間內 — 它們的名稱不需要引入即可見。 - 前向引用不被支援:輔助函數必須在調用它們的源文件內定義。
- 模組路徑映射到文件系統路徑:
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::*(通配符) — 選擇性引入可能會破壞枚舉變體的運算符比較。