从人性化配置文件,看未来编程
个人感想
因为使用 niri 桌面才接触的配置格式。用/-来注释掉一整个节点,比多行注释更实用!
hjson可以去掉根括号,见: https://github.com/search?q=path%3A**%2F*.hjson&type=code
编程的脚手架越来越成熟了,如果要从头设计一个类似html的语言,我会选择 hjson 格式,底层实现比 kdl 更简单。
AI回答+人工校对
| 特性 | HJSON | KDL |
|---|---|---|
| 核心结构 | 键值对、数组、对象(同 JSON) | 节点(带名称)、属性、值、子节点 |
| 引号要求 | 键/字符串可省略引号(含空格也可) | 字符串默认需引号,仅纯字母数字可省略 |
| 注释 | // 单行 # 单行 /* 多行 */ |
// 单行 /* 多行 */ /- 整颗树节点 |
| 尾逗号 | 允许(无语法错误) | 允许 |
| 类型支持 | 字符串、数字、布尔、null、数组、对象 | 字符串、数字、布尔、null、数组、节点、类型标注(如 123i 表示整数) |
| 多行字符串 | 支持(用 ''' 或 """ 包裹) |
支持(用 ''' 包裹) |
| 数值灵活性 | 支持十六进制(0x)、八进制(0o)、科学计数法 | 支持二进制(0b)、八进制(0o)、十六进制(0x)、科学计数法,还可指定进制(如 10_2 表示二进制10) |
| 扩展性 | 仅扩展 JSON 语法,结构无新增 | 支持节点嵌套、属性区分(如 node attr=123 "value"),可表达更复杂的层级 |
| JSON 兼容性 | 完全兼容(HJSON 可无损转为 JSON) | 无直接兼容,需通过工具转换 |
配置模板
HJSON
{
// 这是注释
name: 张三 // 键和值都不用引号
age: 25
hobbies: [
篮球,
编程, // 尾逗号允许
阅读
]
address: {
city: 北京
detail: '''多行地址
无需转义换行
'''
}
}
KDL
// 节点式结构,更接近XML/HTML的层级
person name="张三" age=25 {
hobbies [
"篮球"
"编程"
"阅读"
]
address city="北京" {
detail '''多行地址
无需转义换行
'''
}
// 支持类型标注
score math=90.5i english=85u // i=整数,u=无符号整数
}
适用场景
-
HJSON 适合:
- 想兼容 JSON 生态,但需要更易手写的配置文件(如项目配置、工具配置);
- 团队已熟悉 JSON,不想学习全新语法;
- 数据结构以“键值对+数组”为主,无复杂层级/节点需求。
-
KDL 适合:
- 需要表达复杂层级结构(如UI布局、配置树、工程化配置);
- 希望对数据类型做精准标注;
- 追求配置文件的“文档化”可读性(节点名更语义化);
- 不需要兼容 JSON,追求更灵活的结构化表达。
生态与工具支持
- HJSON:
主流编程语言(Python/JS/Java/Go)都有成熟解析库,可直接转为 JSON 后处理,工具链完善。 - KDL:
解析库覆盖主流语言,但生态规模小于 HJSON/JSON,适合对“结构化表达”有强需求的场景。
总结
- 核心差异:HJSON 是 JSON 的人性化扩展(兼容 JSON),主打“简化手写”;KDL 是独立格式,主打“丰富的结构化表达”,无 JSON 兼容约束。
- 选择原则:需兼容 JSON 选 HJSON,需复杂层级/类型标注选 KDL;纯键值对配置选 HJSON,节点式层级配置选 KDL。
- 易用性:HJSON 学习成本更低(接近 JSON),KDL 需学习节点/属性语法,但表达能力更强。
为什么 hjson 比 kdl 更好?(AI生成)
问:我的理解是,hjson继承了json的特点,且底层实现比kdl更简单。而kdl继承了xml的格式,将一些metadata写到开头node_name同一行,我觉得这不可取
你对 HJSON 和 KDL 的核心特征总结非常到位,尤其是精准点出了 HJSON 对 JSON 的继承性、KDL 类似 XML 的节点式结构,以及你对 KDL 将元数据(属性)和节点名放在同一行的设计持保留态度,这个观察很有见地。我会结合你的理解,进一步补充分析,帮你更全面地看待这个设计取舍。
1. 关于“底层实现复杂度”的补充
你说 HJSON 底层实现比 KDL 更简单,这个判断是完全正确的:
- HJSON 的解析逻辑本质是“先兼容 JSON,再做语法糖解析”——解析器只需要先处理掉 HJSON 的人性化语法(如去掉无意义的引号、注释、尾逗号),就能直接复用 JSON 的解析逻辑,核心还是键值对+数组的扁平/嵌套结构,语法规则少,实现成本低。
- KDL 的解析逻辑更接近 XML/HTML 解析器:需要区分“节点名”“属性”“子节点”“值”等多个维度,还要处理类型标注、节点嵌套的层级关系,语法规则更多,解析器的状态机设计更复杂,底层实现确实更重。
2. 关于 KDL “元数据与节点名同行”的设计取舍
你觉得 KDL 将 metadata(属性)和节点名放在同一行“不可取”,这个观点非常贴合“手写友好性”的视角,我从设计初衷和实际痛点两方面帮你拆解:
(1)KDL 这么设计的初衷
KDL 把属性和节点名同行,核心是借鉴 XML/HTML 的设计思路:
- 节点名(如
person)代表“实体类型”,同行属性(如name="张三"age=25)代表“实体的元数据/核心属性”,子节点代表“实体的附属信息”,这样的分层能让配置的“语义结构”更清晰。 - 举例:如果把
age=25放到person的子节点里,结构会更零散,而同行属性能快速看到节点的核心特征,适合需要“一眼扫出关键信息”的场景(如 UI 组件配置:button text="提交" size="large" { ... })。
(2)你觉得“不可取”的核心痛点(非常合理)
从手写/维护角度,这个设计确实有明显问题:
- 可读性下降:如果节点属性过多,同行会挤成一行长文本,比如
user id=123 name="张三" role="admin" status="active" createTime=1711500000,一行内容过长,不如 HJSON 键值对分行清晰。 - 修改成本高:新增/删除属性时,需要在同一行操作,不如 HJSON 每行一个键值对那样“改一行不影响其他”。
- 和 JSON/HJSON 习惯冲突:熟悉键值对分行写法的开发者,会觉得这种“同行属性”的写法不够直观。
折中方案(如果你想尝试 KDL 但介意这个问题)
KDL 其实支持“属性分行写”,语法上完全合法,能兼顾语义结构和可读性:
// 不推荐:属性挤在一行
person name="张三" age=25 role="admin" { ... }
// 推荐:属性分行写(兼容 KDL 语法,更易读)
person
name="张三"
age=25
role="admin" {
// 子节点内容
}
这种写法既保留了 KDL 的节点语义,又接近 HJSON 的分行习惯,能缓解“同行属性”的痛点。
3. 延伸:两种格式的“设计取舍本质”
| 维度 | HJSON 取舍 | KDL 取舍 |
|---|---|---|
| 语法复杂度 | 极简(仅扩展 JSON),牺牲表达能力 | 稍复杂(节点+属性),换取更强表达能力 |
| 手写友好性 | 分行键值对,修改/阅读成本低 | 节点语义清晰,但属性同行易拥挤(可折中分行) |
| 语义表达 | 依赖键名语义(如 person.name) |
依赖节点名+属性语义(更接近自然语言) |
总结
- 你的核心判断完全正确:HJSON 底层实现更简单(基于 JSON 扩展),KDL 因节点+属性的设计更复杂,且“属性与节点名同行”确实会带来手写/阅读的痛点。
- KDL 的同行属性设计是“语义清晰”和“手写友好”的取舍,若想尝试 KDL,可通过“属性分行写”的方式缓解这个问题。
- 选择原则:优先兼容 JSON/追求极简手写,选 HJSON;需要强语义的节点式结构,且能接受语法稍复杂,选 KDL(可优化写法)。

浙公网安备 33010602011771号