YAML 的语法规则

YAML 的语法规则由它的设计目标决定:让人类轻松读写。它用缩进表达层级,用符号简化结构,但它对格式的细节很敏感。

以下从基础到进阶,把 YAML 的规则拆解清楚。


一、基础规则:大小写敏感 + 缩进

规则 1:大小写敏感

YAML 区分大小写。Serverserver 是两个不同的键。

规则 2:缩进用空格,不用 Tab

YAML 强制使用空格进行缩进。Tab 会导致解析错误。Spring Boot 的 YAML 解析器会直接报错,不会自动转换。

yaml 复制代码
# 正确:用两个空格缩进
server:
  port: 8080

# 错误:Tab 缩进(解析失败)
server:
	port: 8080

规则 3:相同层级的元素左对齐

yaml 复制代码
server:
  port: 8080
  context-path: /api    # 与 port 左对齐

database:
  url: jdbc:mysql://... # 与 server 左对齐(不同父节点)

规则 4:: 后面必须有空格

键值对中,冒号后面必须加一个空格。这是语法要求。

yaml 复制代码
# 正确
name: myapp

# 错误(缺少空格)
name:myapp

二、数据结构表达

1. 对象(Map / 字典)

通过缩进表示层级。

yaml 复制代码
server:
  port: 8080
  timeout: 30
  host: localhost

等价于 JSON:

json 复制代码
{
  "server": {
    "port": 8080,
    "timeout": 30,
    "host": "localhost"
  }
}

内联写法:

yaml 复制代码
server: { port: 8080, timeout: 30, host: localhost }

2. 数组(List / 序列)

- 加空格表示列表项。

yaml 复制代码
servers:
  - server1
  - server2
  - server3

等价于 JSON:

json 复制代码
{
  "servers": ["server1", "server2", "server3"]
}

内联写法:

yaml 复制代码
servers: [server1, server2, server3]

3. 对象列表

数组中的每个元素是一个对象。

yaml 复制代码
users:
  - name: zhangsan
    age: 25
    email: zhangsan@example.com
  - name: lisi
    age: 30
    email: lisi@example.com

等价于 JSON:

json 复制代码
{
  "users": [
    { "name": "zhangsan", "age": 25, "email": "zhangsan@example.com" },
    { "name": "lisi", "age": 30, "email": "lisi@example.com" }
  ]
}

4. 嵌套组合

yaml 复制代码
app:
  name: myapp
  version: 1.0
  features:
    cache: true
    logging: false
  servers:
    - prod-server
    - dev-server
  security:
    enabled: true
    roles:
      - admin
      - user

三、纯量(Scalar)数据类型

1. 字符串

默认不加引号。包含特殊字符时用引号包裹。

yaml 复制代码
# 普通字符串
name: myapp

# 包含空格
description: This is my application

# 包含特殊字符(需要引号)
message: 'Hello: World'        # 包含冒号
path: 'C:\Users\admin'         # 包含反斜杠
quote: "He said: 'Hello'"      # 包含单引号

单引号 vs 双引号:

yaml 复制代码
# 单引号:原样输出,不解析转义
single: 'Hello \n World'       # 输出:Hello \n World

# 双引号:解析转义字符
double: "Hello \n World"       # 输出:Hello(换行) World

2. 多行字符串

保留换行(|):

yaml 复制代码
description: |
  This is the first line.
  This is the second line.
  This is the third line.

去掉末尾换行(>-):

yaml 复制代码
description: >-
  This line will be folded.
  This is the second line.
  # 最终拼接为一行:This line will be folded. This is the second line.

3. 数字

yaml 复制代码
integer: 100
float: 3.14
negative: -50
exponential: 1.2e+5

4. 布尔值

支持多种写法:

yaml 复制代码
enabled: true       # 真
disabled: false     # 假

# 也支持以下写法
on: true
off: false
yes: true
no: false

5. Null

yaml 复制代码
value: null
value: ~      # 等价写法

6. 日期和时间

yaml 复制代码
date: 2024-01-01
datetime: 2024-01-01T10:30:00+08:00

四、高级语法

1. 注释

# 添加注释。注释可以单独占一行,也可以跟在值后面。

yaml 复制代码
# 服务器配置
server:
  port: 8080  # 监听端口
  timeout: 30 # 超时时间(秒)

2. 锚点(&)与引用(*)

复用配置片段。

yaml 复制代码
defaults: &defaults
  timeout: 30
  retries: 3

server1:
  <<: *defaults
  host: server1.example.com

server2:
  <<: *defaults
  host: server2.example.com
  timeout: 60  # 覆盖默认值

解析后,server1 包含 timeout: 30retries: 3host: server1.example.comserver2timeout 被覆盖为 60。

3. 多文档块(---

一个 YAML 文件中可以包含多个文档,用 --- 分隔。

yaml 复制代码
# 第一个文档
spring:
  profiles: dev
  datasource:
    url: jdbc:h2:mem:dev

---
# 第二个文档
spring:
  profiles: prod
  datasource:
    url: jdbc:mysql://prod:3306/db

Spring Boot 利用这个机制实现多 Profile 配置(配合 spring.config.activate.on-profile)。

4. 强制类型转换

yaml 复制代码
string_value: !!str 100
integer_value: !!int "100"
boolean_value: !!bool "true"

5. 空值标记

yaml 复制代码
empty_list: []        # 空数组
empty_map: {}         # 空对象
null_value: null      # 空值

五、Spring Boot 中的特殊规则

1. @Value 注入列表

yaml 复制代码
servers:
  - server1
  - server2
java 复制代码
@Value("${servers}")
private List<String> servers; // 自动拆分

2. @ConfigurationProperties 绑定

yaml 复制代码
app:
  name: myapp
  timeout: 30
  features:
    cache: true
    logging: false
java 复制代码
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private int timeout;
    private Map<String, Boolean> features;
}

3. 配置文件加载顺序中的规则

YAML 和 properties 可以共存。同一个键在两种格式中都出现时,properties 优先级更高(先加载 YAML,后加载 properties,后者覆盖前者)。


六、常见错误

错误 1:缩进不一致

yaml 复制代码
# 错误(2 空格和 4 空格混用)
server:
    port: 8080
  timeout: 30

错误 2:冒号后缺少空格

yaml 复制代码
# 错误
name:myapp

错误 3:使用 Tab

yaml 复制代码
# 错误(使用了 Tab)
server:
	port: 8080

错误 4:列表项缩进不对

yaml 复制代码
# 错误(列表项未左对齐)
servers:
  - server1
   - server2

错误 5:字符串中包含特殊字符未加引号

yaml 复制代码
# 错误(冒号在字符串中)
description: this is: a test

# 正确(加引号)
description: 'this is: a test'

错误 6:注释前缺少空格

yaml 复制代码
# 正确
port: 8080  # 监听端口

# 错误(# 前无空格,但 YAML 仍能解析,是风格问题)
port: 8080# 监听端口

七、总结

YAML 的关键规则:

规则 说明
缩进 只用空格,不用 Tab,相同层级左对齐
冒号 键值对中冒号后必须有空格
列表 - 后必须有空格
类型 自动推断,必要时用引号控制
注释 # 开头
多文档 --- 分隔
引用 & 定义锚点,* 引用

YAML 的设计目标是让人类能轻松读写配置。缩进替代了 XML 的闭合标签和 JSON 的括号,这让它高度可读,也意味着任何格式错误都会导致解析失败。写配置时记住两点:缩进保持一致,冒号后面加空格,就能避免 90% 的格式问题。

相关推荐
骇客野人1 小时前
SpringBoot电商系统用户注册、登录、留存及数据埋点设计与落地实施方案
java·spring boot·后端
摇滚侠1 小时前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 数据库初始化机制 阅读笔记 36
数据库·spring boot·笔记
wxwx_bscxy3222 小时前
基于Python新冠疫情可视化分析系统的设计与实现
java·数据库·spring boot·python·微信小程序·sqlite
IT_陈寒4 小时前
React的状态更新坑得我差点加班到天亮
前端·人工智能·后端
码事漫谈5 小时前
一天搭出 80% 的 Agent,然后卡在 95% 到死
后端
leonkay5 小时前
C# 锁机制——【2】深入原理
开发语言·后端·spring·c#·个人开发
江湖十年5 小时前
在 Go 中使用 dyno 包处理动态对象
后端·面试·go
八角丶5 小时前
Node 网络编程 —— TLS 模块
javascript·后端·node.js
摇滚侠6 小时前
《SpringBoot 3:入门与应用实战》第 9 章 跨域问题 阅读笔记 27
spring boot·笔记·okhttp