附录:对照与排查
附录:对照与排查
本附录把 SML 和常见格式做对照,并列出新手最常遇到的错误及解决办法。可作工具书随时翻。
A.1 与 JSON / YAML / TOML 对照
| 能力 | SML | JSON | YAML | TOML |
|---|---|---|---|---|
| 引号可选 | ✅ 裸词即字符串 | ❌ 必须 | ✅(但有类型推断坑) | ✅ |
| 逗号可选 | ✅ | ❌ | ✅ | ❌ |
| 块冒号可省 | ✅ a { } ≡ a: { } |
— | ✅ | — |
| 缩进敏感 | ❌ 靠 {} |
❌ 靠 {} |
✅ 易错 | 部分 |
| 片段复用 | ✅ @base/&base |
❌ | ❌(锚点复杂) | ❌ |
| 命名空间 include | ✅ as ns |
❌ | ❌ | ❌ |
| 契约 / Schema | ✅ 内建 | ❌ | ❌ | ❌ |
| 环境变量注入 | ✅ $env |
❌ | ❌ | ❌ |
A.2 常见错误排查
| 现象 | 原因 | 解决 |
|---|---|---|
| 字符串被截断 | 值含空格却用了裸词 | 加引号 "..." |
| 片段没展开 | 块内裸写 &base |
写成 key: &base(值位置) |
| 契约报"未声明字段" | 默认严格模式 | 契约名后加 loose,或移除多余字段 |
port 超范围报错 |
min/max 约束生效 |
改正值,或放宽区间 |
$env.X 变空串 |
变量未设置(正常) | 运行时确认环境变量已导出 |
| include 找不到文件 | 路径相对被包含文件目录 | 检查相对路径;确认文件存在 |
| 循环 include 报错 | A 包含 B,B 又包含 A | 打破循环依赖 |
@is 报契约未定义 |
契约在 @is 之后才写 |
把 @contract 移到 @is 之前 |
| 命名空间冲突 | 同 ns 重复定义 @name/@contract |
改名,或用不同 as ns |
A.3 语法速查
键值: key: value
裸词串: state: NY
引号串: name: "John Doe"
整数: age: 27
浮点: ratio: 0.75
布尔: on: true
空值: x: null
对象块: a { b: 1 } ≡ a: { b: 1 }
数组: list: [ a b c ]
行注释: # -- //
块注释: /* ... */ _* ... *_
片段定义: @name { ... }
片段引用: key: &name
契约定义: @contract Name loose { field: type ... }
契约应用: @is Name
include: include "x.sml" (内联)
include "ui" as ui (命名空间)
include "a", "b" as y (多目标,需 feature)
环境变量: secret: $env.API_KEY
转义: "line1\nline2 \u{2744}"
A.4 版本与 feature
文件开头可声明版本:
@version v1
复杂能力按需开启:
@feature enable glob regex
include "widgets/*.sml"
默认开启 include + namespace + implicit-ns(极简三件套);multi / glob / regex / ext-rewrite 默认关,需显式 opt-in。
反馈与版本
本书随 swsml 0.4.0 发布。源码与更新:/book/。反馈请到 SML 仓库 issue 区。
全书完。回到 教科书首页。
动手练习
读完本章,在下面的编辑器里直接修改 SML 并点“运行”,立刻看到解析结果或校验错误——有输出才能高效学习。
✍ 动手练习
写出一段 SML:name(John)、age(27)、address 块含 city=NY、tags 数组长度 2。这段在任意语言解析结果都应一致。
💡 提示:把这段分别想象成 Rust/C/JS/Lua 解析,字段名与嵌套结构应完全相同。
Q1. 与 JSON 相比,SML 的显著区别是?
SML 裸词省引号、空格/换行分隔省逗号,用花括号定界;无需像 JSON 那样严格加引号逗号。
Q2. 判断:SML 的契约系统(@contract)在 JSON Schema 里没有直接等价物。
SML 把契约内建进配置语言本身,JSON 需额外 Schema 文件,二者定位不同。
Q3. 排查“字段未生效”时,优先检查?
配置不生效多因字段名拼错、命名空间没引用、或 strict 契约把多余字段丢弃。