从人性化配置文件,看未来编程

个人感想

因为使用 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 适合

    1. 想兼容 JSON 生态,但需要更易手写的配置文件(如项目配置、工具配置);
    2. 团队已熟悉 JSON,不想学习全新语法;
    3. 数据结构以“键值对+数组”为主,无复杂层级/节点需求。
  • KDL 适合

    1. 需要表达复杂层级结构(如UI布局、配置树、工程化配置);
    2. 希望对数据类型做精准标注;
    3. 追求配置文件的“文档化”可读性(节点名更语义化);
    4. 不需要兼容 JSON,追求更灵活的结构化表达。

生态与工具支持

  • HJSON
    主流编程语言(Python/JS/Java/Go)都有成熟解析库,可直接转为 JSON 后处理,工具链完善。
  • KDL
    解析库覆盖主流语言,但生态规模小于 HJSON/JSON,适合对“结构化表达”有强需求的场景。

总结

  1. 核心差异:HJSON 是 JSON 的人性化扩展(兼容 JSON),主打“简化手写”;KDL 是独立格式,主打“丰富的结构化表达”,无 JSON 兼容约束。
  2. 选择原则:需兼容 JSON 选 HJSON,需复杂层级/类型标注选 KDL;纯键值对配置选 HJSON,节点式层级配置选 KDL。
  3. 易用性: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 依赖节点名+属性语义(更接近自然语言)

总结

  1. 你的核心判断完全正确:HJSON 底层实现更简单(基于 JSON 扩展),KDL 因节点+属性的设计更复杂,且“属性与节点名同行”确实会带来手写/阅读的痛点。
  2. KDL 的同行属性设计是“语义清晰”和“手写友好”的取舍,若想尝试 KDL,可通过“属性分行写”的方式缓解这个问题。
  3. 选择原则:优先兼容 JSON/追求极简手写,选 HJSON;需要强语义的节点式结构,且能接受语法稍复杂,选 KDL(可优化写法)。
posted @ 2026-02-27 15:36  Nolca  阅读(2)  评论(0)    收藏  举报