翻译尚未覆盖全部内容。完整技术参考请查阅英文原文。 查看英文版本 →

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 等文件使用了这种模式。

模块解析规则

  1. 带有 module X::Y 的文件必须通过 use X::Y::* 或 use X::Y::{name} 导入。
  2. 没有 module 的文件位于扁平命名空间 —— 其名称无需导入即可见。
  3. 不支持前向引用:辅助函数必须在调用者之前定义。
  4. 模块路径映射到文件系统路径: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::*(通配符)—— 选择性导入可能会破坏枚举变体上的运算符比较。