TOC

TOML

我之前说过,YAML 太过复杂,复杂到根本不适合用来作为配置文件。应该是有很多人和我一样想,然后就设计了 TOML 语言。

TOML 就是 Tom's Obvious Minimal Language 的缩写,翻译过来就是汤姆的最精简语言(作者全名 Tom Preston-Werner)。
然后,Slogan 就是 A config file format for humans 也就是:以人为本的配置文件格式。
它的定位已经很明确了吧!

PS: 据说这个语言来自 GitHub(作者的另一个身份是 GitHub 联合创始人)。

其语法说明就只有一个不长的单页面:https://toml.io/cn/v1.0.0
其语法 ABNF 文件,算上注释和空行,一共 243 行。

之前的配置文件格式

  1. xml
  2. ini
  3. json
  4. yaml

TOML 语法

数据类型

个人归类:

  1. 基础类型:数值型(整数,小数),字符串,布尔型
  2. 时间类型:时间,日期,时刻
  3. 复合类型:数组,表

  4. 字符串

    1. 三个单引号,三个双引号表示多行字符串
    2. 单引号不转义,双引号转义
  5. 整数
    1. 支持 0b 二进制、0o 八进制、0x 十六进制表示法
    2. 支持下划线隔开,增强可读性
    3. inf/+inf, -inf, nan/+nan, -nan
  6. 浮点数
  7. 布尔值 true/false
  8. 时间 RFC3339 规范,比如 2020-09-07T19:00:00Z,允许不带时区。
  9. 日期 2020-09-07
  10. 时刻 07:32:00, 07:32:00.999 如果带小数,至少有三位小数,精确到毫秒
  11. 数组 [ 1, 2, 3 ]
    1. 允许混合类型
    2. 可与跨行

[table-1]
key1 = "some string"
key2 = 123

[dog."tater.man"]
type.name = "pug"

等于:

{
    "table-1": {
        "key1": "some string",
        "key2": 123
    },
    "dog": {
        "tater.man": {
            "type": {
                "name": "pug"
            }
        }
    }
}
  1. 键名周围的空格会被忽略 [ a. b . c ] = [a.b.c]

内联表

紧凑的写法:

name = { first = "Tom", last = "Preston-Werner" }

等于:

{
    "name": {
        "first": "Tom",
        "last": "Preston-Werner"
    }
}
  1. 内联表不能继续扩充,比如 name.middle = "Green"
  2. 内联表也不能用于扩充或覆盖一个已经存在的表

表数组

[[fruits]]
name = "apple"

[fruits.physical]  # 子表
color = "red"
shape = "round"

[[fruits.varieties]]  # 嵌套表数组
name = "red delicious"

[[fruits.varieties]]
name = "granny smith"

[[fruits]]
name = "banana"

[[fruits.varieties]]
name = "plantain"

相当于:

{
    "fruits": [
        {
            "name": "apple",
            "physical": {
                "color": "red",
                "shape": "round"
            },
            "varieties": [{ "name": "red delicious" }, { "name": "granny smith" }]
        },
        {
            "name": "banana",
            "varieties": [{ "name": "plantain" }]
        }
    ]
}

基本格式

key = "value"           # 裸键 A-Za-z0-9_-
"键名" = "键值"         # 引号键,允许是空字符串

hosts."gmail.com" = { timeout = 300 }

description = """
支持多行字符串。
就这么简单!
"""         # 开头的换行会被忽略

等于:

{
    "key": "value",
    "键名": "键值",
    "hosts": {
        "gmail.com": {
            "timeout": 300
        }
    },
    "description": "支持多行字符串。\n就这么简单!\n"
}

参考资料与拓展阅读