YAML 有哪些数据类型?最容易踩的坑是什么?
YAML 的数据类型分三大类:标量(字符串、数字、布尔、空值)、序列(列表)、映射(键值对)。解析器会根据值的书写格式自动推断类型,但也支持用 !!标签 显式指定。
字符串最灵活:默认不需要引号,但含特殊字符时必须加引号。单引号不转义('Hello\nWorld' 输出原样),双引号会转义("Hello\nWorld" 输出换行)。多行文本用 | 保留换行,用 > 折叠成一行。
数字支持整数(十进制、0o 八进制、0x 十六进制)、浮点数和科学计数法(1.23e4)。
布尔值有三个等价组:true/yes/on 和 false/no/off。这是 YAML 1.1 的遗留问题,很多解析器在 YAML 1.2 下只认 true/false。
空值用 null、~ 或直接留空。
序列用 - 表示列表项,映射用 key: value。两者都能内联书写([a, b, c] 和 {k: v}),也支持任意嵌套组合。
类型推断最容易踩坑:yes、no、on、off 会被当成布尔值;裸写的 2024-01-01 会被解析成日期对象;纯数字如 8080 会变成整数。要强制为字符串就加引号。
追问
YAML 和 JSON 的数据类型有什么区别?
JSON 只有六种类型(对象、数组、字符串、数字、布尔、null)。YAML 在此基础上增加了日期时间、二进制、集合等类型,还支持多行字符串、锚点别名、显式类型标签。YAML 是 JSON 的超集——合法的 JSON 也是合法的 YAML。
实际项目里遇到过什么坑?
最经典的就是布尔值陷阱。Kubernetes 配置里写 env: no,K8s 把它解析成 false 而不是字符串 "no"。Docker Compose 也有类似问题。解法:需要字符串的值一律加引号。
为什么 YAML 1.2 废弃了 yes/no/on/off 布尔值?
YAML 1.1 设计时追求"自然语言友好",认为 yes/no 比 true/false 更直观。实际使用中这些词频繁出现在配置值里(国家代码 NO、环境名 on),类型误判 bug 爆棚。YAML 1.2 规范只保留了 true/false,但很多解析器为了向后兼容仍然支持旧写法。
如何强制指定类型?什么场景需要?
用 !!标签 语法:!!str 123 强制为字符串,!!int "42" 强制为整数,!!timestamp 指定日期。场景:配置值可能被误推断时(如版本号 "2.0" 需要字符串而非浮点数),或者需要精确控制输出类型时(如 API 配置里的端口号必须是整数)。
写段代码
yaml# 类型陷阱示例 port: "8080" # 字符串,不加引号会变成整数 country: "NO" # 字符串,不加引号会变成 false version: !!str 2.0 # 强制字符串,否则变成浮点数 2.0 date: 2024-01-01 # 自动解析为日期对象 flag: !!bool "true" # 强制布尔,从字符串转换