golang支持TOML格式解析与查询的插件库go-toml的使用

Golang 支持 TOML 格式解析与查询的插件库 go-toml 的使用

介绍

go-toml 是一个用于处理 TOML 格式的 Go 语言库,支持 TOML v1.0.0 规范。它提供了类似于标准库 encoding/json 的使用体验,同时注重性能。

安装

import "github.com/pelletier/go-toml/v2"

对于不同 Go 版本:

  • Go ≥ 1.16: 无需额外操作
  • Go ≥ 1.13: GO111MODULE=on go get github.com/pelletier/go-toml/v2

基本使用示例

定义配置结构体

type MyConfig struct {
    Version int
    Name    string
    Tags    []string
}

解析 TOML (Unmarshal)

doc := `
version = 2
name = "go-toml"
tags = ["go", "toml"]
`

var cfg MyConfig
err := toml.Unmarshal([]byte(doc), &cfg)
if err != nil {
    panic(err)
}
fmt.Println("version:", cfg.Version)
fmt.Println("name:", cfg.Name)
fmt.Println("tags:", cfg.Tags)

// 输出:
// version: 2
// name: go-toml
// tags: [go toml]

生成 TOML (Marshal)

cfg := MyConfig{
    Version: 2,
    Name:    "go-toml",
    Tags:    []string{"go", "toml"},
}

b, err := toml.Marshal(cfg)
if err != nil {
    panic(err)
}
fmt.Println(string(b))

// 输出:
// Version = 2
// Name = 'go-toml'
// Tags = ['go', 'toml']

高级功能

带注释的配置

go-toml 可以生成带注释的 TOML 配置:

# Host IP to connect to.
host = '127.0.0.1'
# Port of the remote server.
port = 4242

# Encryption parameters (optional)
# [TLS]
# cipher = 'AEAD-AES128-GCM-SHA256'
# version = 'TLS 1.3'

严格模式

可以启用严格模式,当 TOML 文档中有字段在目标结构中不存在时会报错:

decoder := toml.NewDecoder(reader)
decoder.DisallowUnknownFields() // 启用严格模式
err := decoder.Decode(&config)

本地日期和时间支持

支持 TOML 的本地日期/时间类型:

type Event struct {
    Date toml.LocalDate
    Time toml.LocalTime
    DateTime toml.LocalDateTime
}

性能

go-toml v2 相比其他 TOML 库有显著性能提升:

Benchmark go-toml v1 BurntSushi/toml
Marshal/HugoFrontMatter-2 1.9x 2.2x
Marshal/ReferenceFile/map-2 1.7x 2.1x
Marshal/ReferenceFile/struct-2 2.2x 3.0x
Unmarshal/HugoFrontMatter-2 2.9x 2.7x
Unmarshal/ReferenceFile/map-2 2.6x 2.7x
Unmarshal/ReferenceFile/struct-2 4.6x 5.1x

命令行工具

go-toml 提供了三个有用的命令行工具:

  1. tomljson: 将 TOML 转换为 JSON

    $ go install github.com/pelletier/go-toml/v2/cmd/tomljson[@latest](/user/latest)
    $ tomljson example.toml
    
  2. jsontoml: 将 JSON 转换为 TOML

    $ go install github.com/pelletier/go-toml/v2/cmd/jsontoml[@latest](/user/latest)
    $ jsontoml example.json
    
  3. tomll: 格式化 TOML 文件

    $ go install github.com/pelletier/go-toml/v2/cmd/tomll[@latest](/user/latest)
    $ tomll example.toml
    

从 v1 迁移

主要变化包括:

  • 字段名匹配改为大小写不敏感
  • 接口中的现有值会被忽略
  • 移除了 toml.Unmarshaler 支持
  • 移除了 default 结构体标签
  • 移除了 toml.Tree 类型
  • 默认结构体字段顺序改为定义顺序
  • 默认不使用缩进
  • 字符串和键使用单引号

许可证

MIT 许可证。


更多关于golang支持TOML格式解析与查询的插件库go-toml的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang支持TOML格式解析与查询的插件库go-toml的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Go-Toml 库使用指南

Go-Toml 是一个用于 Go 语言的 TOML 格式解析和查询库,它提供了简单易用的 API 来处理 TOML 配置文件。

安装

go get github.com/pelletier/go-toml/v2

基本用法

1. 解析 TOML 文件

package main

import (
	"fmt"
	"log"
	"os"

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

func main() {
	// 读取 TOML 文件内容
	data, err := os.ReadFile("config.toml")
	if err != nil {
		log.Fatal(err)
	}

	// 解析 TOML
	var config map[string]interface{}
	err = toml.Unmarshal(data, &config)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Config: %+v\n", config)
}

2. 生成 TOML 文件

package main

import (
	"fmt"
	"log"
	"os"

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

func main() {
	config := map[string]interface{}{
		"title": "TOML Example",
		"owner": map[string]interface{}{
			"name": "Tom Preston-Werner",
			"dob":  "1979-05-27T07:32:00-08:00",
		},
		"database": map[string]interface{}{
			"server":  "192.168.1.1",
			"ports":   []int{8001, 8001, 8002},
			"enabled": true,
		},
	}

	// 生成 TOML
	data, err := toml.Marshal(config)
	if err != nil {
		log.Fatal(err)
	}

	// 写入文件
	err = os.WriteFile("output.toml", data, 0644)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("TOML file generated successfully")
}

3. 使用结构体解析

package main

import (
	"fmt"
	"log"
	"os"
	"time"

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

type Config struct {
	Title  string
	Owner  Owner
	DB     Database `toml:"database"`
	Server struct {
		IP string `toml:"ip"`
		DC string `toml:"dc"`
	}
}

type Owner struct {
	Name string
	Dob  time.Time
}

type Database struct {
	Server  string
	Ports   []int
	Enabled bool
}

func main() {
	data, err := os.ReadFile("config.toml")
	if err != nil {
		log.Fatal(err)
	}

	var cfg Config
	err = toml.Unmarshal(data, &cfg)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Title: %s\n", cfg.Title)
	fmt.Printf("Owner: %s (%v)\n", cfg.Owner.Name, cfg.Owner.Dob)
	fmt.Printf("Database: %s %v %t\n", cfg.DB.Server, cfg.DB.Ports, cfg.DB.Enabled)
	fmt.Printf("Server: %s @ %s\n", cfg.Server.IP, cfg.Server.DC)
}

4. 查询特定值

package main

import (
	"fmt"
	"log"
	"os"

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

func main() {
	data, err := os.ReadFile("config.toml")
	if err != nil {
		log.Fatal(err)
	}

	var cfg interface{}
	err = toml.Unmarshal(data, &cfg)
	if err != nil {
		log.Fatal(err)
	}

	// 类型断言获取值
	configMap := cfg.(map[string]interface{})
	title := configMap["title"].(string)
	fmt.Println("Title:", title)

	// 获取嵌套值
	owner := configMap["owner"].(map[string]interface{})
	ownerName := owner["name"].(string)
	fmt.Println("Owner Name:", ownerName)

	// 获取数组
	database := configMap["database"].(map[string]interface{})
	ports := database["ports"].([]interface{})
	fmt.Println("Ports:")
	for _, port := range ports {
		fmt.Println("-", port.(int64))
	}
}

5. 使用 Tree 结构

package main

import (
	"fmt"
	"log"

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

func main() {
	// 创建一个新的 Tree
	tree, err := toml.Load(`
		[owner]
		name = "Tom Preston-Werner"
		dob = 1979-05-27T07:32:00-08:00
		
		[database]
		server = "192.168.1.1"
		ports = [8001, 8001, 8002]
		enabled = true
	`)
	if err != nil {
		log.Fatal(err)
	}

	// 查询值
	ownerName := tree.Get("owner.name").(string)
	fmt.Println("Owner:", ownerName)

	// 修改值
	tree.Set("owner.name", "John Doe")
	tree.Set("database.ports", []int{9001, 9002})

	// 添加新值
	tree.Set("new.key", "value")

	// 获取修改后的 TOML
	newToml := tree.String()
	fmt.Println("\nModified TOML:")
	fmt.Println(newToml)
}

高级特性

1. 自定义时间格式

package main

import (
	"fmt"
	"log"
	"time"

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

type Config struct {
	CreatedAt time.Time
}

func main() {
	data := []byte(`createdAt = 2023-01-01T12:00:00Z`)

	var cfg Config
	err := toml.Unmarshal(data, &cfg)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Created at:", cfg.CreatedAt)
}

2. 严格模式解析

package main

import (
	"fmt"
	"log"

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

type Config struct {
	Title string
}

func main() {
	data := []byte(`
		title = "Example"
		unknown = "field"
	`)

	var cfg Config
	decoder := toml.NewDecoder(data)
	decoder.DisallowUnknownFields() // 启用严格模式

	err := decorder.Decode(&cfg)
	if err != nil {
		log.Fatal(err) // 会报错,因为有未知字段
	}

	fmt.Println("Title:", cfg.Title)
}

总结

Go-Toml 提供了完整的 TOML 格式支持,包括:

  1. 解析 TOML 文件到 Go 数据结构
  2. 将 Go 数据结构序列化为 TOML
  3. 方便的查询和修改功能
  4. 支持时间、数组、嵌套结构等复杂类型
  5. 严格模式等高级特性

对于大多数 Go 项目中的配置管理需求,Go-Toml 都是一个优秀的选择。

回到顶部