第 2 章:块与嵌套
第 2 章:块与嵌套
上一章只有扁平的键值。真实配置是有层级的——一个人有"地址",一个服务有"数据库设置"。本章学对象块和数组。
2.1 对象块(嵌套键值)
用花括号 {} 把一组键值包起来,就是一个"块":
address: {
street: "21 2nd Street"
city: New York
state: NY
}
冒号可以省掉——这是 SML 的特色:
address {
street: "21 2nd Street"
city: New York
state: NY
}
上面两种写法完全等价。address { } ≡ address: { },你喜欢哪种就用哪种。
2.2 块可以无限嵌套
database {
primary {
host: db1.internal
port: 5432
}
replica {
host: db2.internal
port: 5432
}
}
关键点:SML 不依赖缩进来定层级,靠的是花括号。所以你可以自由缩进,缩进错了对解析没影响(但建议保持缩进,对人友好)。
2.3 数组
方括号 [] 表示数组。元素之间逗号可省,换行也可:
tags: [ logging metrics tracing ] # 裸词数组,逗号可省
ports: [ 80, 443, 8080 ] # 带逗号也行
empty: []
数组元素也可以是块(对象数组):
endpoints: [
{ path: /health method: GET }
{ path: /api/v1 method: POST }
]
数组里的块同样支持"冒号可省":
users: [
{ name: alice role: admin }
{ name: bob role: user }
]
2.4 顶层三种形态
一个 SML 文件顶层可以是:
-
键值 / 块混排(最常见)
name: gateway database { host: db1 } -
纯数组(适合"记录列表",如发信历史)
[ { ts: 2026-08-30T10:00 to: a@b.c status: ok } { ts: 2026-08-30T11:00 to: x@y.z status: fail } ] -
单个对象块
{ name: gateway port: 8080 }
顶层标量(比如单独写个
42)不可往返——SML 顶层必须是"容器"。这是格式固有限制。
2.5 动手试一试
把第 1 章的"名片"升级成有层级的结构:
name: 张三
contact {
email: zhangsan@example.com
phone: "138-0000-0000"
}
skills: [ rust sml linux ]
解析后你会得到:name="张三"、contact.email=...、skills 是一个含 3 个元素的数组。
动手练习
读完本章,在下面的编辑器里直接修改 SML 并点“运行”,立刻看到解析结果或校验错误——有输出才能高效学习。
✍ 动手练习
写一个 address 块(street、city="New York"、state=NY),一个 database 块含 primary/replica 两个子块(各含 host、port=5432),一个 users 数组,元素是含 name/role 的块。
💡 提示:试试把 address { } 写成 address: { },结果是否一样?
Q1. address { city: NY } 和 address: { city: NY } 两种写法结果一样吗?
SML 中块前的冒号可省,address { } 与 address: { } 等价,都是对象块。
Q2. 下面哪个能正确表示一个数组?
数组用方括号 [ ] 包裹;方括号内元素用空格分隔,逗号也可省略。
Q3. 行内对象 { name: alice role: admin } 正确的是?
行内对象 { } 内字段用空格分隔,role: admin 紧跟 name: alice 即可。
Q4. 判断:SML 的数组可以混合不同类型,如 [ 1 "two" true ]。
SML 不限制数组元素类型,[ 1 "two" true ] 是合法的异构数组。