3、YAML数据类型:标量类型(字符串、数字、布尔、空值)、序列(列表)、映射(字典)
好,咱们今天来聊聊 YAML 的数据类型。说实话,YAML 之所以能火,很大程度上就是因为它对数据类型的表达特别「人性化」。你不需要像写 JSON 那样纠结于引号、逗号,也不用像 XML 那样写一堆标签。YAML 的设计哲学就是——让数据自己说话。
我个人习惯把 YAML 的数据类型分成三大类:标量、序列 和 映射。说白了,就是「单个值」、「一列值」和「键值对」。你想想看,任何复杂的配置,拆到最底层,无非就是这三种东西的组合。
核心要点:YAML 的数据类型是动态推断的,你不需要显式声明类型。但正因为如此,有些「坑」需要特别注意。
3.1 标量类型:最基础的数据单元
标量,就是单个值。它可以是字符串、数字、布尔值,或者空值。嗯,这里要注意,YAML 对类型的推断非常「智能」,但有时候也会聪明反被聪明误。
3.1.1 字符串
字符串是 YAML 里最常用的类型。大多数情况下,你不需要加引号:
name: 张三
city: 北京
description: 这是一个普通的字符串
但有些情况你必须加引号。我记得有一次在配置 Kubernetes 的 Deployment 时,有个字段的值是 true,结果 YAML 解析器把它当成了布尔值,导致部署失败。后来排查了半天才发现是这个问题。
避坑指南:当字符串包含特殊字符(如 :、#、!)或以数字开头时,建议用引号包裹。我曾经因为一个版本号 1.0.0 没加引号,被解析成了浮点数,结果 CI/CD 流水线直接崩了。
多行字符串也是 YAML 的亮点。用 | 保留换行,用 > 折叠换行:
# 保留换行
description: |
这是第一行
这是第二行
这是第三行
# 折叠换行(变成一行)
summary: >
这是第一行
这是第二行
这是第三行
3.1.2 数字
YAML 支持整数、浮点数、科学计数法,甚至支持进制表示:
integer: 42
float: 3.14
scientific: 1.23e+4
hex: 0x1A
octal: 0o17
exponential: 1.5e-3
这里有个小细节——YAML 会把 0123 当成八进制数(在旧版本中)。我个人习惯在数字前加 0 时一定用引号包起来,避免歧义。
3.1.3 布尔值
布尔值在 YAML 里有很多种写法,但建议统一用 true 和 false:
enabled: true
disabled: false
# 以下写法也合法,但不推荐
active: yes
inactive: no
on: on
off: off
我的建议:团队协作时,统一用 true/false。你想想看,如果有人在配置里写 yes,另一个人写 true,后期维护起来多头疼。
3.1.4 空值
空值用 null 或 ~ 表示,也可以直接留空:
# 三种写法等价
value1: null
value2: ~
value3: # 留空也表示 null
嗯,这里要注意,留空的方式虽然简洁,但在某些解析器中可能会被忽略。我建议显式写 null,这样代码更清晰。
3.2 序列:有序的数据集合
序列就是列表,用短横线 - 表示。说白了,就是一组有序的值。
3.2.1 块序列
这是最常用的写法,每个元素占一行:
fruits:
- apple
- banana
- cherry
# 也可以写成一行(流序列)
fruits: [apple, banana, cherry]
序列里可以放任何类型,包括嵌套的序列和映射:
users:
- name: 张三
age: 28
- name: 李四
age: 32
- name: 王五
age: 25
我在项目中遇到过一种情况——有人把序列的缩进搞错了,结果 YAML 解析成了映射。记住:序列的 - 后面必须跟一个空格,而且同一层级的序列元素缩进必须一致。
3.3 映射:键值对的集合
映射就是字典,用 key: value 的形式表示。这是 YAML 里最灵活、最常用的结构。
3.3.1 块映射
person:
name: 张三
age: 28
address:
city: 北京
street: 长安街
映射的键可以是任何标量类型,但通常用字符串。你想想看,如果用数字做键,虽然合法,但可读性会大打折扣。
3.3.2 流映射
流映射用花括号包裹,适合简短的键值对:
person: {name: 张三, age: 28, city: 北京}
实战经验:我个人习惯在配置文件中用块映射,因为可读性更好。流映射适合在 CI/CD 脚本或命令行参数中使用,节省空间。
3.4 类型推断的陷阱
YAML 的类型推断虽然方便,但有几个常见的坑:
| 写法 | YAML 推断的类型 | 实际意图 | 建议 |
|---|---|---|---|
0123 |
八进制数(旧版) | 字符串 "0123" | 加引号 |
yes |
布尔值 true | 字符串 "yes" | 加引号或用 true |
null |
空值 | 字符串 "null" | 加引号 |
1.0 |
浮点数 1.0 | 字符串 "1.0" | 加引号 |
我曾经踩过的坑:有一次在配置 Prometheus 的告警规则时,把 severity: critical 写成了 severity: critical(拼写错误),结果 YAML 解析器把它当成了普通字符串,没有任何报错。告警规则静默失效了整整一周才被发现。所以,YAML 的「宽容」有时候反而是隐患。
3.5 实战:组合使用
在实际的 DevOps 配置中,这三种类型往往是组合使用的。来看一个典型的 Docker Compose 配置:
version: "3.8" # 字符串,加引号避免被解析为浮点数
services:
web: # 映射
image: nginx:latest # 字符串
ports: # 序列
- "80:80"
- "443:443"
environment: # 映射
- NGINX_HOST=example.com
- NGINX_PORT=80
restart: always # 字符串
db: # 映射
image: postgres:13
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret123
volumes: # 序列
- db_data:/var/lib/postgresql/data
volumes: # 映射
db_data: # 空值,等价于 null
你看,这个配置里标量、序列、映射全用上了。说白了,YAML 的威力就在于用最少的符号表达最复杂的结构。
我的习惯:写 YAML 配置时,我会先画一个简单的结构图,确定哪些是映射、哪些是序列。这样写出来的配置层次清晰,不容易出错。
好了,这一章的内容就到这里。记住:标量是砖瓦,序列是架子,映射是图纸。三者配合,才能盖出稳固的配置大楼。