3、YAML数据类型:标量类型(字符串、数字、布尔、空值)、序列(列表)、映射(字典)

好,咱们今天来聊聊 YAML 的数据类型。说实话,YAML 之所以能火,很大程度上就是因为它对数据类型的表达特别「人性化」。你不需要像写 JSON 那样纠结于引号、逗号,也不用像 XML 那样写一堆标签。YAML 的设计哲学就是——让数据自己说话。

我个人习惯把 YAML 的数据类型分成三大类:标量、序列 和 映射。说白了,就是「单个值」、「一列值」和「键值对」。你想想看,任何复杂的配置,拆到最底层,无非就是这三种东西的组合。

核心要点:YAML 的数据类型是动态推断的,你不需要显式声明类型。但正因为如此,有些「坑」需要特别注意。

YAML 数据类型 标量 (Scalar) 序列 (Sequence) 映射 (Mapping) 字符串 数字 布尔 块序列 流序列 块映射 流映射 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 配置时,我会先画一个简单的结构图,确定哪些是映射、哪些是序列。这样写出来的配置层次清晰,不容易出错。

好了,这一章的内容就到这里。记住:标量是砖瓦,序列是架子,映射是图纸。三者配合,才能盖出稳固的配置大楼。

可可精品资料库