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、-inf 和 nan。
# 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布尔值
布尔值只有小写的 true 和 false。与 YAML 不同,TOML 不接受 yes、no、on、off 作为布尔值。
# 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.9999993. 表(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 = true4. 数组
数组是包含在方括号中的有序值列表。数组可以包含相同类型或混合类型的值(自 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:597. 注释
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 literal8. 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 = 19. pyproject.toml — Python 项目配置
pyproject.toml 是 Python 项目的标准配置文件,定义在 PEP 518 和 PEP 621 中。它将构建系统配置和工具设置统一到一个文件中,取代了 setup.py、setup.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 = true10. 其他值得注意的 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 = 3Deno — 现代 JavaScript/TypeScript 运行时支持 deno.toml 和 deno.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
以下是并排对比,帮助你决定使用哪种格式:
| 特性 | TOML | YAML | JSON |
|---|---|---|---|
| 注释 | 支持(#) | 支持(#) | 不支持 |
| 原生日期/时间 | 支持(RFC 3339) | 支持(隐式) | 不支持(仅字符串) |
| 深层嵌套 | 较冗长(表头) | 优雅(缩进) | 良好(大括号) |
| 歧义性 | 无 | 高(隐式转换) | 无 |
| 多行字符串 | 支持(""" 和 ''') | 支持(| 和 >) | 不支持(仅 \n) |
| 主要生态 | Rust、Python、Go | DevOps、K8s、Ansible | Web 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 转换器,它会报告解析错误。