DevToolBox免费
博客

TOML 语法与配置指南

9 分钟阅读作者 DevToolBox

TOML(Tom 的明显最小化语言)是一种配置文件格式,因其语义明显而易于阅读。TOML 由 Tom Preston-Werner(GitHub 联合创始人)于 2013 年创建,能明确映射到哈希表,现已成为 Rust、Python 和许多其他工具的标准配置格式。本综合 TOML 语法指南通过实际示例涵盖了所有特性。

使用我们的免费工具在 TOML 和 YAML 之间即时转换 →

使用我们的免费工具在 JSON 和 YAML 之间即时转换 →

1. 什么是 TOML?

TOML 全称 Tom's Obvious Minimal Language(Tom 的明显最小化语言)。它被设计为一种最小化的配置文件格式,因语义明显而易于阅读。TOML 旨在能明确映射到哈希表,并且在各种编程语言中都易于解析为数据结构。

TOML 的设计目标:

  • 最小化 — 规范刻意保持精简和稳定
  • 明显 — 语义清晰,不像 YAML 那样有隐式类型转换
  • 无歧义 — 每个有效的 TOML 文档都只有一种含义
  • 哈希表友好 — 能直接映射到字典/对象/映射

与 JSON 相比,TOML 支持注释、原生日期/时间类型和多行字符串。与 YAML 相比,TOML 避免了隐式类型转换的陷阱(著名的"挪威问题",即 NO 变成 false)和缩进敏感性。TOML 于 2021 年 1 月达到 v1.0.0,成为稳定的规范。

# example.toml — a simple TOML configuration
title = "My Application"

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00

[database]
enabled = true
ports = [8001, 8001, 8002]
data = [["delta", "phi"], [3.14]]
temp_targets = { cpu = 79.5, case = 72.0 }

2. 基本数据类型

TOML 原生支持七种数据类型。每个值必须是以下类型之一:

字符串

TOML 有四种字符串:基本字符串、多行基本字符串、字面量字符串和多行字面量字符串。

# Basic string — supports escape sequences
name = "Tom Preston-Werner"
escaped = "Line 1\nLine 2\tTabbed"
unicode = "\u03B1 is alpha"

# Literal string — no escaping
winpath = 'C:\Users\Tom\config'
regex = '<\i\c*\s*>'

# Multi-line basic string
bio = """
Roses are red,
Violets are blue.\
  This line is joined."""

# Multi-line literal string
regex2 = '''
I [dw]on't need \d{2} escapes
'''

整数

整数是整数值。可以使用下划线提高可读性。也支持十六进制、八进制和二进制表示。

# Integers
int1 = +99
int2 = 42
int3 = 0
int4 = -17

# Underscores for readability
big_number = 1_000_000
hex_color = 0xDEADBEEF

# Different bases
hex = 0xDEADBEEF    # hexadecimal
oct = 0o755          # octal (Unix permissions)
bin = 0b11010110     # binary

浮点数

浮点数遵循 IEEE 754。支持特殊值 inf+inf-infnan

# Floats
flt1 = +1.0
flt2 = 3.1415
flt3 = -0.01
flt4 = 5e+22
flt5 = 1e06
flt6 = -2E-2

# Underscores
flt7 = 224_617.445_991_228

# Special float values
sf1 = inf      # positive infinity
sf2 = +inf     # positive infinity
sf3 = -inf     # negative infinity
sf4 = nan      # not a number

布尔值

布尔值只有小写的 truefalse。与 YAML 不同,TOML 不接受 yesnoonoff 作为布尔值。

# Booleans — only true and false (lowercase)
bool1 = true
bool2 = false

# INVALID in TOML (unlike YAML):
# bool3 = yes     # ERROR
# bool4 = no      # ERROR
# bool5 = on      # ERROR
# bool6 = off     # ERROR
# bool7 = True    # ERROR — must be lowercase

日期和时间

TOML 对日期/时间有一等支持,包含四种类型:带偏移的日期时间、本地日期时间、本地日期和本地时间。全部遵循 RFC 3339。

# Offset Date-Time (with timezone)
odt1 = 1979-05-27T07:32:00Z
odt2 = 1979-05-27T00:32:00-07:00
odt3 = 1979-05-27T00:32:00.999999-07:00

# Local Date-Time (no timezone)
ldt1 = 1979-05-27T07:32:00
ldt2 = 1979-05-27T00:32:00.999999

# Local Date
ld1 = 1979-05-27

# Local Time
lt1 = 07:32:00
lt2 = 00:32:00.999999

3. 表(Tables)

表(也称为哈希表或字典)是键/值对的集合。它们以方括号的形式单独出现在一行中。表头之后的所有键/值对都属于该表,直到下一个表头出现。

# Standard table
[server]
host = "localhost"
port = 8080

[server.tls]
enabled = true
cert = "/path/to/cert.pem"
key = "/path/to/key.pem"

# Empty table
[empty_table]

内联表为简单表提供了紧凑的语法。它们必须出现在同一行中:

# Inline tables — must fit on one line
point = { x = 1, y = 2 }
animal = { type.name = "pug" }
name = { first = "Tom", last = "Preston-Werner" }

# Equivalent standard table form:
# [name]
# first = "Tom"
# last = "Preston-Werner"

点号键允许在不使用显式表头的情况下定义嵌套表:

# Dotted keys create nested tables implicitly
fruit.apple.color = "red"
fruit.apple.taste.sweet = true

# Equivalent to:
# [fruit.apple]
# color = "red"
#
# [fruit.apple.taste]
# sweet = true

4. 数组

数组是包含在方括号中的有序值列表。数组可以包含相同类型或混合类型的值(自 TOML v1.0 起)。

# Basic arrays
integers = [1, 2, 3]
colors = ["red", "yellow", "green"]
nested_arrays = [[1, 2], [3, 4, 5]]

# Multi-line arrays (trailing comma OK)
hosts = [
  "alpha",
  "omega",
  "beta",    # trailing comma is allowed!
]

# Mixed-type arrays (TOML v1.0+)
mixed = [1, "two", 3.0, true, 1979-05-27]

表数组使用双括号 [[array]] 定义。每次使用双括号都会向数组添加一个元素:

# Array of tables — each [[products]] adds an entry
[[products]]
name = "Hammer"
sku = 738594937

[[products]]    # empty table in the array

[[products]]
name = "Nail"
sku = 284758393
color = "gray"

# This is equivalent to the JSON:
# {
#   "products": [
#     { "name": "Hammer", "sku": 738594937 },
#     {},
#     { "name": "Nail", "sku": 284758393, "color": "gray" }
#   ]
# }

# Nested array of tables
[[fruits]]
name = "apple"

  [[fruits.varieties]]
  name = "red delicious"

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

[[fruits]]
name = "banana"

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

5. 字符串类型详解

TOML 提供了四种字符串类型来处理各种场景:

基本字符串用双引号(")包围。支持转义序列如 \n\t\\\u0041

# Basic string escape sequences
str1 = "I'm a string.\n"         # newline
str2 = "Tabs\there."              # tab
str3 = "Backslash: \\"           # literal backslash
str4 = "Quote: \""               # literal double quote
str5 = "Unicode: \u0041"         # 'A'
str6 = "Unicode: \U0001F600"     # emoji

字面量字符串用单引号(')包围。不进行任何转义 — 所见即所得。非常适合 Windows 路径和正则表达式。

# Literal strings — no escape processing
winpath = 'C:\Users\nodejs\templates'
regex = '\d{2} files? found\?'

多行基本字符串用三个双引号(""")包围。换行符被保留。行尾的反斜杠会裁剪换行符和后续空白。

# Multi-line basic string
str1 = """
Roses are red
Violets are blue"""

# Line-ending backslash trims newline + whitespace
str2 = """\
  The quick brown \
  fox jumps over \
  the lazy dog."""
# Result: "The quick brown fox jumps over the lazy dog."

多行字面量字符串用三个单引号(''')包围。不转义,换行符被保留。

# Multi-line literal string — no escaping at all
regex_example = '''
I [dw]on't need \d{2} escapes
'''

raw_html = '''
<div>
  <p>Hello, world!</p>
</div>
'''

6. 日期和时间类型

TOML 原生支持四种日期/时间格式,全部基于 RFC 3339:

带偏移的日期时间 — 完整的带时区偏移的时间戳:

# Offset date-time — includes timezone
odt1 = 1979-05-27T07:32:00Z           # UTC
odt2 = 1979-05-27T00:32:00-07:00      # UTC-7
odt3 = 1979-05-27 07:32:00Z           # space instead of T is OK

本地日期时间 — 不包含时区信息:

# Local date-time — no timezone
ldt1 = 1979-05-27T07:32:00
ldt2 = 1979-05-27T00:32:00.999999

本地日期 — 仅日期:

# Local date
ld1 = 1979-05-27
ld2 = 2024-01-15

本地时间 — 仅时间:

# Local time
lt1 = 07:32:00
lt2 = 00:32:00.999999
lt3 = 23:59:59

7. 注释

TOML 使用井号(#)支持单行注释。注释从 # 字符开始到行尾结束。TOML 不支持多行注释 — 每一行都需要自己的 #

注释可以出现在值后面的行尾,也可以独占一行。不能出现在字符串内部。

# This is a full-line comment
key = "value"  # This is an end-of-line comment

# Comments can explain configuration choices
[database]
# Use port 5432 for production PostgreSQL
port = 5432

# TOML does NOT support multi-line comments
# Each line needs its own # symbol
# Like these three lines

# You CANNOT put comments inside strings:
str = "has a # character"  # this is a comment, but the # in the string is literal

8. Cargo.toml — Rust 包管理

Cargo.toml 是 Rust 项目的清单文件。它定义了包的元数据、依赖项、特性和构建配置。理解 TOML 语法对每个 Rust 开发者来说都是必不可少的。

Cargo.toml 的关键段落:

  • [package] — 名称、版本、版次、描述、许可证
  • [dependencies] — 外部 crate 依赖
  • [dev-dependencies] — 仅用于测试和示例的依赖
  • [build-dependencies] — 构建脚本的依赖
  • [features] — 条件编译标志
  • [workspace] — 多包项目配置
  • [[bin]] — 二进制目标(表数组)
# Cargo.toml — Complete Rust project example
[package]
name = "my-web-server"
version = "0.1.0"
edition = "2021"
authors = ["Alice <alice@example.com>"]
description = "A fast web server"
license = "MIT"
repository = "https://github.com/alice/my-web-server"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
axum = "0.7"
tracing = "0.1"

[dev-dependencies]
reqwest = { version = "0.12", features = ["json"] }
tokio-test = "0.4"

[features]
default = ["json"]
json = ["serde/derive"]
full = ["json", "tracing"]

# Workspace configuration for monorepos
[workspace]
members = [
  "crates/core",
  "crates/api",
  "crates/cli",
]

# Binary targets
[[bin]]
name = "server"
path = "src/main.rs"

[[bin]]
name = "cli"
path = "src/cli.rs"

# Build profile optimization
[profile.release]
opt-level = 3
lto = true
codegen-units = 1

9. pyproject.toml — Python 项目配置

pyproject.toml 是 Python 项目的标准配置文件,定义在 PEP 518 和 PEP 621 中。它将构建系统配置和工具设置统一到一个文件中,取代了 setup.pysetup.cfg 和各个工具的独立配置文件。

常见段落:

  • [build-system] — 构建后端规范(setuptools、hatch、poetry 等)
  • [project] — 项目元数据(名称、版本、依赖、Python 版本)
  • [tool.ruff] — Ruff 代码检查器配置
  • [tool.black] — Black 格式化器配置
  • [tool.pytest.ini_options] — pytest 设置
  • [tool.mypy] — mypy 类型检查器设置
  • [tool.poetry] — Poetry 特定的包管理
# pyproject.toml — Complete Python project example
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "my-package"
version = "1.0.0"
description = "A useful Python package"
readme = "README.md"
license = "MIT"
requires-python = ">=3.9"
authors = [
  { name = "Alice", email = "alice@example.com" },
]
dependencies = [
  "requests>=2.28",
  "pydantic>=2.0",
  "click>=8.0",
]

[project.optional-dependencies]
dev = [
  "pytest>=7.0",
  "ruff>=0.1",
  "mypy>=1.0",
]

[project.scripts]
my-cli = "my_package.cli:main"

# Ruff linter configuration
[tool.ruff]
line-length = 88
target-version = "py39"

[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP"]
ignore = ["E501"]

[tool.ruff.lint.isort]
known-first-party = ["my_package"]

# Black formatter
[tool.black]
line-length = 88
target-version = ["py39", "py310", "py311"]

# Pytest configuration
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-ra -q --strict-markers"
markers = [
  "slow: marks tests as slow",
  "integration: integration tests",
]

# Mypy type checking
[tool.mypy]
python_version = "3.9"
strict = true
warn_return_any = true

10. 其他值得注意的 TOML 配置

TOML 被 Rust 和 Python 之外的许多工具和平台使用:

Hugo — 流行的静态网站生成器使用 hugo.toml(原 config.toml)作为主要配置格式。Hugo 支持 TOML、YAML 和 JSON,但 TOML 是默认且最常用的选择。

# hugo.toml — Hugo static site generator
baseURL = "https://example.com/"
languageCode = "en-us"
title = "My Hugo Site"
theme = "ananke"

[params]
author = "Alice"
description = "A blog about technology"
showReadingTime = true

[menu]
[[menu.main]]
name = "Home"
url = "/"
weight = 1

[[menu.main]]
name = "Posts"
url = "/posts/"
weight = 2

[[menu.main]]
name = "About"
url = "/about/"
weight = 3

Deno — 现代 JavaScript/TypeScript 运行时支持 deno.tomldeno.json 用于项目配置。TOML 变体支持注释,而 JSON 不支持。

# deno.toml — Deno runtime configuration
# Comments are supported (unlike deno.json)

[tasks]
dev = "deno run --watch main.ts"
test = "deno test --allow-read"
lint = "deno lint"

[fmt]
indentWidth = 2
lineWidth = 100
singleQuote = true

[lint.rules]
tags = ["recommended"]

[compilerOptions]
lib = ["deno.window"]

Taplo — 一个 TOML 工具包,包含格式化器、验证器和语言服务器。它通过 taplo.toml 配置为 VS Code 和其他编辑器中的 TOML 文件提供 IDE 支持。

git-cliff — 通过 cliff.toml 配置的变更日志生成器。

Starship — 跨 Shell 提示符使用 starship.toml 进行自定义。

Alacritty — GPU 加速终端模拟器使用 alacritty.toml 作为配置文件(2023 年从 YAML 迁移)。

# starship.toml — cross-shell prompt
[character]
success_symbol = "[❯](bold green)"
error_symbol = "[❯](bold red)"

[git_branch]
symbol = "🌿 "
style = "bold purple"

[nodejs]
symbol = "⬢ "
detect_files = ["package.json", ".node-version"]

# alacritty.toml — terminal emulator
[font]
size = 14.0

[font.normal]
family = "JetBrains Mono"
style = "Regular"

[colors.primary]
background = "#1d1f21"
foreground = "#c5c8c6"

11. TOML vs YAML vs JSON

以下是并排对比,帮助你决定使用哪种格式:

特性TOMLYAMLJSON
注释支持(#)支持(#)不支持
原生日期/时间支持(RFC 3339)支持(隐式)不支持(仅字符串)
深层嵌套较冗长(表头)优雅(缩进)良好(大括号)
歧义性高(隐式转换)
多行字符串支持(""" 和 ''')支持(| 和 >)不支持(仅 \n)
主要生态Rust、Python、GoDevOps、K8s、AnsibleWeb API、Node.js
规范大小小(约 3000 词)大(约 80 页)极小(约 600 词)

12. 常见问题

TOML 和 INI 文件有什么区别?

虽然 TOML 的 [section] 头部看起来类似于 INI 文件,但 TOML 是一个定义良好的规范,具有严格的类型系统、嵌套表、数组、日期/时间支持和 Unicode 处理。INI 文件没有正式规范,导致不同实现之间的解析不一致。TOML 可以被认为是 INI 格式的现代标准化演进。

TOML 支持 null 值吗?

不支持,TOML 有意不支持 null/nil/None 值。如果一个键不存在,就意味着该值未设置。这是一个刻意的设计选择,旨在保持格式的简单和无歧义。如果需要表示"无值",只需完全省略该键,或在应用逻辑中使用空字符串或哨兵值。

TOML 文件可以引用或包含其他 TOML 文件吗?

不可以,TOML 规范不支持文件包含、导入或引用。每个 TOML 文件都是自包含的。如果需要将配置分散到多个文件中,该逻辑必须在应用程序中实现。一些工具如 Hugo 支持配置目录,可以自动合并多个 TOML 文件。

TOML 文件应该使用什么扩展名?

TOML 文件的标准扩展名是 .toml。知名的 TOML 文件如 Cargo.toml 和 pyproject.toml 都使用此扩展名。由于历史原因,某些工具使用不带 .toml 扩展名的特定名称,但 .toml 始终是新配置的推荐选择。

如何验证 TOML 文件?

可以使用多种方法验证 TOML 文件:(1) 使用 Taplo,一个带有 CLI 验证器和 VS Code 扩展的 TOML 工具包;(2) 使用在线验证器如 toml-lint;(3) 使用特定语言的库如 toml(Python)、toml-rs(Rust)或 @iarna/toml(Node.js)进行解析并捕获错误;(4) 使用我们的在线 TOML 转 YAML 转换器,它会报告解析错误。

使用我们的免费工具在 TOML 和 YAML 之间即时转换 →

使用我们的免费工具在 JSON 和 YAML 之间即时转换 →

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

TYTOML ↔ YAMLY{}JSON ↔ YAML ConverterYMLYAML Validator & Formatter

相关文章

JSON vs YAML vs TOML:你应该用哪种配置格式?

比较 JSON、YAML 和 TOML 配置格式,了解语法、特性和优缺点,选择适合你项目的格式。

YAML 语法与验证:常见错误及修复方法

掌握 YAML 语法:缩进规则、常见解析错误、数据类型和配置文件最佳实践。