Skip to content

Catalog 边界

Catalog 的职责是解析用户输入,而不是定义单位身份。这个边界决定了 LunarUnits 如何处理符号、别名和自定义单位。

问题

实际应用中,用户输入通常来自字符串:m/s^2NHzkg。这些符号需要解析,但符号本身不应该成为核心单位模型的全局状态。

如果把 Catalog 做成全局 mutable registry,会带来几个问题:

  • 不同模块注册同一个符号时,行为依赖加载顺序。
  • 测试之间可能互相污染。
  • 同一段解析代码在不同上下文下得到不同结果。
  • 核心 unit identity 被用户界面符号影响。

选择

LunarUnits 把 Catalog 设计成不可变查找值。Parser 接收一个 Catalog,并基于它解析单位表达式。扩展 Catalog 会返回新值,而不是修改全局表。

这样,解析上下文由调用方显式传入。CLI、Web UI、测试和领域应用都可以拥有自己的符号表。

避免的错误

这个边界避免了“看不见的全局注册”导致的行为漂移。解析失败也可以被应用层清楚处理,而不是在 core 层制造隐式依赖。

代价

代价是调用 parser 时必须携带 catalog。相比全局默认表,这多了一点样板代码;但换来的是可测试、可复现、可组合的解析行为。

边界

Catalog 不参与单位的数学身份判断。单位是否兼容由 dimension 和 unit scale 决定;Catalog 只负责把用户写下的符号映射到单位。

使用建议

通用应用可以从 @preset.all() 开始,因为它覆盖内置单位包。领域应用可以在此基础上添加局部别名,例如 forceflow 或业务系统中的标准缩写。也可以按输入范围只组合部分领域的 Catalog。

重复绑定同一个符号时,后写入的绑定生效。这个能力适合局部上下文里的别名或覆盖;公共 CLI、教程和共享配置应尽量避免让常见符号产生歧义。