Skip to content

TOML(Tom's Obvious, Minimal Language) ​

TOML(Tom's Obvious, Minimal Language)是一种配置文件格式,设计目标是一眼能读懂、好写也好解析。它的语法源自 INI 文件,但支持更复杂的结构,语法规则也更严格。

1. TOML 文件格式 ​

TOML 文件格式的基本组成包括:

  1. 键值对(Key-Value Pairs):

    • TOML 文件使用键值对来表示数据。键和值之间用等号(=)分隔。例如:
      toml
      key = "value"
  2. 节(Tables):

    • TOML 文件使用节来组织配置数据,节用方括号([])表示。例如:
      toml
      [section]
      key = "value"
  3. 子节(Subtables):

    • TOML 支持嵌套节,允许在节中定义子节。例如:
      toml
      [parent]
      key = "value"
      
      [parent.child]
      key = "value"
  4. 数组(Arrays):

    • TOML 支持一维数组和多维数组。例如:
      toml
      array = [1, 2, 3]
  5. 日期和时间(Date and Time):

    • TOML 支持 ISO 8601 格式的日期和时间。例如:
      toml
      date = 2024-07-25
      datetime = 2024-07-25T14:30:00
  6. 注释(Comments):

    • 注释以井号(#)开头,注释内容被忽略。例如:
      toml
      # This is a comment
      key = "value"
  7. 多行字符串(Multiline Strings):

    • TOML 支持多行字符串,以三个双引号(""")括起来。例如:
      toml
      multiline_string = """
      This is a
      multiline string
      """

2. TOML 文件的示例 ​

以下是一个示例 TOML 文件,展示了各种功能:

toml
# This is a TOML file example

[server]
host = "localhost"
port = 8080

[database]
user = "admin"
password = "secret"
dbname = "example_db"

[features]
enabled = true
version = 1.0

[paths]
data = "/path/to/data"
logs = "/path/to/logs"

[servers]
[servers.alpha]
ip = "192.168.1.1"
port = 9000

[servers.beta]
ip = "192.168.1.2"
port = 9001

[[items]]
name = "Item1"
value = 10

[[items]]
name = "Item2"
value = 20
  • [server]:节名,用于定义服务器配置。
  • [database]:节名,用于定义数据库配置。
  • [features]:节名,用于定义特性开关和版本。
  • [paths]:节名,用于定义路径配置。
  • [servers]:节名,包含子节 alpha 和 beta,用于定义多个服务器配置。
  • [[items]]:数组节,每个数组元素表示一个项。

3. TOML 的优点和缺点 ​

优点:

  1. 人类可读:

    • 纯文本格式,读起来和编辑都容易。
  2. 支持复杂数据结构:

    • TOML 支持嵌套节、数组和多行字符串,适合表达复杂的配置数据。
  3. 语法规则严格:

    • 规则明确,解析时歧义少,出错的可能性小。

缺点:

  1. 有限的工具支持:

    • 尽管 TOML 得到了一定的支持,但与一些更常见的格式(如 JSON、YAML)相比,支持工具和库相对较少。
  2. 不支持自定义数据类型:

    • TOML 不支持自定义数据类型或结构,只能使用基本类型(字符串、整数、浮点数、布尔值、日期等)。

4. TOML 文件的应用 ​

TOML 最常见的用途是应用程序配置,用来定义程序的参数和选项;系统设置、服务配置和开发环境配置里也常用,只要数据是结构化的就合适。

5. TOML 文件处理示例(Go 语言) ​

在 Go 语言中,可以使用第三方库(如 github.com/pelletier/go-toml)来处理 TOML 文件。以下是一个示例代码,展示了如何读取和写入 TOML 文件。

读取 TOML 文件示例:

读取要求当前目录已有 config.toml,可以先运行下面的写入示例生成,也可以手写一份,例如:

toml
[server]
host = "localhost"
port = 8080
go
package main

import (
    "fmt"
    "log"

    "github.com/pelletier/go-toml"
)

func main() {
    // 读取 TOML 文件
    data, err := toml.LoadFile("config.toml")
    if err != nil {
        log.Fatalf("Failed to read file: %v", err)
    }

    // 读取节
    server := data.Get("server").(*toml.Tree)

    // 读取键值对,注意 TOML 中的整数会被解析为 int64
    host := server.Get("host").(string)
    port := server.Get("port").(int64)

    fmt.Printf("Host: %s\n", host)
    fmt.Printf("Port: %d\n", port)
}

输出:

plaintext
Host: localhost
Port: 8080

写入 TOML 文件示例:

go
package main

import (
    "log"
    "os"

    "github.com/pelletier/go-toml"
)

func main() {
    // 用 TreeFromMap 从 map 构建 TOML 树
    data, err := toml.TreeFromMap(map[string]interface{}{
        "server": map[string]interface{}{
            "host": "localhost",
            "port": 8080,
        },
        "database": map[string]interface{}{
            "user":     "admin",
            "password": "secret",
        },
    })
    if err != nil {
        log.Fatalf("Failed to build tree: %v", err)
    }

    // 通过 WriteTo 把 TOML 树写入文件
    file, err := os.Create("config.toml")
    if err != nil {
        log.Fatalf("Failed to create file: %v", err)
    }
    defer file.Close()
    if _, err := data.WriteTo(file); err != nil {
        log.Fatalf("Failed to save file: %v", err)
    }

    log.Println("TOML 文件保存成功")
}

6. TOML 文件处理中的常见问题 ​

  1. 节的命名:

    • 确保节名符合 TOML 的语法要求,不包含非法字符或空格。
  2. 数据类型的转换:

    • TOML 支持基本数据类型,但在读取和写入时需要正确处理类型转换。
  3. 文件编码:

    • 确保 TOML 文件使用 UTF-8 编码,以避免字符编码问题。
  4. 数组的处理:

    • 处理数组时,确保正确使用双括号([[...]])语法,并处理数组元素的排序和重复问题。

总结 ​

TOML 的语法规则明确,节、数组、日期这些结构都能表达,Go 侧用 github.com/pelletier/go-toml 这类库即可读写。工具和库的支持不如 JSON、YAML 普遍,但在配置文件这个场景里够用。

参考资料 ​

同层页面 ​

相关页面 ​

Hello Golang