YAML 基础
- 简介
- 对象
- 数组
- 常量
- 引用
1. 简介
YAML 是专门用来写配置文件的语言,非常简洁和强大!
它的基本语法规则有:
- 大小写敏感;
- 使用缩进表示层级关系;
- 缩进时不允许使用 Tab 键,只允许使用空格;
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可;
YAML 中使用 # 作为注释, Yaml 中只有行注释。
YAML 支持的数据结构有三种:
- 对象: 键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary);
- 数组: 一组按次序排列的值,又称为序列(sequence) / 列表(list);
- 常量:单个的,不可再分的值;
2. YAML 对象
对象的一组键值对,使用冒号结构表示,格式为 key: value,冒号后面要加空格。
animal: pets
同时,YAML 也允许另一种写法,即将所有键值对写成一个行内对象。
hash: { name: dog, age: 1}
可以使用缩进来表示层级关系,如:
key:
value: dog
age: 24
properties 相当于 key.value = dog, key.age = 24 。
3. 数组
一组连词线开头的行,构成一个数组。
lover:
- Cat
- Dog
-
- Cat
- Dog
- Goldfish
properties 相当于 lover = [ Cat, Dog] , [ [Cat, Dog, Goldfish] ]。
相对复杂的例子,如:
companies:
-
id: 1
name: company1
price: 200W
-
id: 2
name: company2
price: 500W
表示,companies 属性是一个数组,每一个数组元素由 id, name, price 三个属性构成。
使用流式的方式表示,即为:
companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]
4. 常量
常量是最基本的、不可再分的值。以下数据类型都属于 Yaml 的常量:
- 整数
- 浮点数
- 字符串
- NULL
- 日期
- 布尔
- 时间
boolean:
- TRUE #true,True都可以
- FALSE #false,False都可以
float:
- 3.14
- 6.8523015e+5 #可以使用科学计数法
int:
- 123
- 0b1010_0111_0100_1010_1110 #二进制表示
null:
nodeName: 'node'
parent: ~ #使用~表示null
string:
- 哈哈
- 'Hello world' #可以使用双引号或者单引号包裹特殊字符
- newline
newline2 #字符串可以拆成多行,每一行会被转化成一个空格
date:
- 2018-02-17 #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime:
- 2018-02-17T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
关于常量中的字符串要注意的是:
- 字符串默认不使用引号表示;
- 如果字符串之中包含空格或特殊字符,需要放在引号之中;
- 单引号和双引号都可以使用,双引号不会对特殊字符转义;
- 单引号之中如果还有单引号,必须连续使用两个单引号转义;
- 多行字符串可以使用 | 保留换行符,也可以使用 > 折叠换行:
this: |
Foo
Bar
that: >
Foo
Bar
属性转换为: { this: 'Foo\nBar\n', that: 'Foo Bar\n' } 。
5. 引用
重复的内容在 YAML 中可以使用 & 来完成锚点定义,使用 * 来完成锚点引用,例如:
hr: - Mark McGwire - &SS Sammy Sosa rbi: - *SS - Ken Griffey
在 hr 中,使用 &SS 为 Sammy Sosa 设置了一个锚点(引用),名称为 SS,在 rbi 中,使用 *SS 引用了该锚点,那么结果为:
{rbi=[Sammy Sosa, Ken Griffey], hr=[Mark McGwire, Sammy Sosa]}
也可定义成如下结构:
SS: &SS Sammy Sosa hr: - Mark McGwire - *SS rbi: - *SS - Ken Griffey
注意,不能独立的定义锚点,比如不能直接这样写: &SS Sammy Sosa;另外,锚点能够定义更复杂的内容,比如:
default: &default - Mark McGwire - Sammy Sosa hr: *default
hr 相当于引用了 default 的数组,注意,hr: *default 要写在同一行。
合并锚点可以将一个锚点内容直接合并到一个对象中,如:
merge: - &CENTER { x: 1, y: 2 } - &LEFT { x: 0, y: 2 } - &BIG { r: 10 } - &SMALL { r: 1 } sample1: <<: *CENTER r: 10 sample2: << : [ *CENTER, *BIG ] other: haha sample3: << : [ *CENTER, *BIG ] r: 100
在 merge 中,定义了四个锚点,分别在 sample 中使用。
sample1 中,<<: *CENTER意思是引用 {x: 1,y: 2},并且合并到 sample1 中,那么合并的结果为:sample1={r=10, y=2, x=1} 。
sample2中,<<: [*CENTER, *BIG] 意思是联合引用 {x: 1,y: 2} 和 {r: 10},并且合并到sample2中,那么合并的结果为:sample2={other=haha, x=1, y=2, r=10} 。
sample3中,引入了 *CENTER, *BIG,还使用了 r: 100 覆盖了引入的 r: 10,所以 sample3 的值为:sample3={r=100, y=2, x=1} 。
再举一例:
defaults: &defaults adapter: postgres host: localhost development: database: myapp_development <<: *defaults test: database: myapp_test <<: *defaults
相当于:
defaults:
adapter: postgres
host: localhost
development:
database: myapp_development
adapter: postgres
host: localhost
test:
database: myapp_test
adapter: postgres
host: localhost
& 用来建立锚点 (defaults),<< 表示合并到当前数据,* 用来引用锚点。
有了合并锚点,就可以在配置中,把相同的基础配置抽取出来,在不同的子配置中加以合并引用。
参考文章:
YAML 1.2 官网教程: https://yaml.org/spec/1.2/spec.html