Module System
Organize code into modules with explicit imports and namespace control.
模块系统
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 将名称引入当前作用域:
// Wildcard import — brings all public names into scope
use ir::profile::*
// The functions are now available directly
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) {
// available without import in other flat-namespace files
}
自托管编译器中的 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 — uses both module and flat-namespace imports
use ir::ir::* // module import: IrFunction, IrModule, etc.
use ir::profile::* // module import: SprofProfile, sprof_parse, etc.
use ir::inline::* // module import: inl_run_pass, etc.
// normalize.sio, const_prop.sio are flat — no import needed
实用建议
- 对于具有清晰接口的库和可复用组件,使用
module。 - 对于共享大量内部辅助函数的紧密耦合的实现文件,使用扁平命名空间。
- 导入 AST 类型时始终使用
use parser::ast::*(通配符)—— 选择性导入可能会破坏枚举变体上的运算符比较。