(Go) 如何使用toml文件?
(Go) How to use toml files?
如题,我想知道如何使用golang中的toml文件
在此之前,我展示了我的 toml 示例。对吗?
[datatitle]
enable = true
userids = [
"12345", "67890"
]
[datatitle.12345]
prop1 = 30
prop2 = 10
[datatitle.67890]
prop1 = 30
prop2 = 10
然后,我想将这些数据设置为结构类型。
因此我想按如下方式访问子元素。
datatitle["12345"].prop1
datatitle["67890"].prop2
提前致谢!
首先获取 BurntSushi 的 toml 解析器:
go get github.com/BurntSushi/toml
BurntSushi 解析 toml 并将其映射到结构,这就是您想要的。
然后执行下面的例子,学习一下:
package main
import (
"github.com/BurntSushi/toml"
"log"
)
var tomlData = `title = "config"
[feature1]
enable = true
userids = [
"12345", "67890"
]
[feature2]
enable = false`
type feature1 struct {
Enable bool
Userids []string
}
type feature2 struct {
Enable bool
}
type tomlConfig struct {
Title string
F1 feature1 `toml:"feature1"`
F2 feature2 `toml:"feature2"`
}
func main() {
var conf tomlConfig
if _, err := toml.Decode(tomlData, &conf); err != nil {
log.Fatal(err)
}
log.Printf("title: %s", conf.Title)
log.Printf("Feature 1: %#v", conf.F1)
log.Printf("Feature 2: %#v", conf.F2)
}
注意 tomlData
以及它如何映射到 tomlConfig
结构。
查看更多示例
使用推荐的 pkg BurntSushi/toml 解决了这个问题!!
我做了如下操作,它是代码的一部分。
[toml 示例]
[title]
enable = true
[title.clientinfo.12345]
distance = 30
some_id = 6
[Golang 示例]
type TitleClientInfo struct {
Distance int `toml:"distance"`
SomeId int `toml:"some_id"`
}
type Config struct {
Enable bool `toml:"enable"`
ClientInfo map[string]TitleClientInfo `toml:"clientinfo"`
}
var config Config
_, err := toml.Decode(string(d), &config)
然后,就可以如我所愿的使用了
config.ClientInfo[12345].Distance
谢谢!
2019 年的一个小更新 - 现在有 BurntSushi/toml 的更新替代品,具有更丰富的 API 来处理 .toml 文件:
pelletier/go-toml (and documentation)
例如有 config.toml
个文件(或在内存中):
[postgres]
user = "pelletier"
password = "mypassword"
除了使用 pelletier/go-toml 将整个事物常规编组和解组为预定义结构(您可以在接受的答案中看到)之外,您还可以查询单个值,如下所示:
config, err := toml.LoadFile("config.toml")
if err != nil {
fmt.Println("Error ", err.Error())
} else {
// retrieve data directly
directUser := config.Get("postgres.user").(string)
directPassword := config.Get("postgres.password").(string)
fmt.Println("User is", directUser, " and password is", directPassword)
// or using an intermediate object
configTree := config.Get("postgres").(*toml.Tree)
user := configTree.Get("user").(string)
password := configTree.Get("password").(string)
fmt.Println("User is", user, " and password is", password)
// show where elements are in the file
fmt.Printf("User position: %v\n", configTree.GetPosition("user"))
fmt.Printf("Password position: %v\n", configTree.GetPosition("password"))
// use a query to gather elements without walking the tree
q, _ := query.Compile("$..[user,password]")
results := q.Execute(config)
for ii, item := range results.Values() {
fmt.Println("Query result %d: %v", ii, item)
}
}
更新
还有 spf13/viper 适用于 .toml 配置文件(以及其他受支持的格式),但在许多情况下可能有点矫枉过正。
更新 2
Viper 并不是真正的 alternative (credits to @GoForth)。
使用解决方案 Viper 你可以在 JSON、TOML、YAML、HCL、INI 和其他文件中使用配置文件属性格式。
创建文件:
./config.toml
首次导入:
import (config "github.com/spf13/viper")
初始化:
config.SetConfigName("config")
config.AddConfigPath(".")
err := config.ReadInConfig()
if err != nil {
log.Println("ERROR", err.Error())
}
并获取值:
config.GetString("datatitle.12345.prop1")
config.Get("datatitle.12345.prop1").(int32)
我正在使用spf13/viper
第 3 包
Status
Project
Starts
Forks
Alive
spf13/viper
Alive
BurntSushi/toml
毒蛇的用法
我尝试用一个table把代码和配置文件的内容放在一起,但是很明显,编辑和最终的结果不符,所以放上图,希望它会让你更容易比较
package main
import (
"github.com/spf13/viper"
"log"
"os"
)
func main() {
check := func(err error) {
if err != nil {
panic(err)
}
}
myConfigPath := "test_config.toml"
fh, err := os.OpenFile(myConfigPath, os.O_RDWR, 0666)
check(err)
viper.SetConfigType("toml") // do not ignore
err = viper.ReadConfig(fh)
check(err)
// Read
log.Printf("%#v", viper.GetString("title")) // "my config"
log.Printf("%#v", viper.GetString("DataTitle.12345.prop1")) // "30"
log.Printf("%#v", viper.GetString("dataTitle.12345.prop1")) // "30" // case-insensitive
log.Printf("%#v", viper.GetInt("DataTitle.12345.prop1")) // 30
log.Printf("%#v", viper.GetIntSlice("feature1.userids")) // []int{456, 789}
// Write
viper.Set("database", "newuser")
viper.Set("owner.name", "Carson")
viper.Set("feature1.userids", []int{111, 222}) // overwrite
err = viper.WriteConfigAs(myConfigPath)
check(err)
}
title = "my config"
[datatitle]
[datatitle.12345]
prop1 = 30
[feature1]
userids = [456,789]
database = "newuser" # New
title = "my config"
[datatitle]
[datatitle.12345]
prop1 = 30
[feature1]
userids = [111,222] # Update
[owner] # New
name = "Carson"
我正在使用这个 [1] go-toml 库。
它非常适合我的使用。我写了这个 [2] go util 来使用 go-toml
处理 containerd config.toml 文件
如题,我想知道如何使用golang中的toml文件
在此之前,我展示了我的 toml 示例。对吗?
[datatitle]
enable = true
userids = [
"12345", "67890"
]
[datatitle.12345]
prop1 = 30
prop2 = 10
[datatitle.67890]
prop1 = 30
prop2 = 10
然后,我想将这些数据设置为结构类型。
因此我想按如下方式访问子元素。
datatitle["12345"].prop1
datatitle["67890"].prop2
提前致谢!
首先获取 BurntSushi 的 toml 解析器:
go get github.com/BurntSushi/toml
BurntSushi 解析 toml 并将其映射到结构,这就是您想要的。
然后执行下面的例子,学习一下:
package main
import (
"github.com/BurntSushi/toml"
"log"
)
var tomlData = `title = "config"
[feature1]
enable = true
userids = [
"12345", "67890"
]
[feature2]
enable = false`
type feature1 struct {
Enable bool
Userids []string
}
type feature2 struct {
Enable bool
}
type tomlConfig struct {
Title string
F1 feature1 `toml:"feature1"`
F2 feature2 `toml:"feature2"`
}
func main() {
var conf tomlConfig
if _, err := toml.Decode(tomlData, &conf); err != nil {
log.Fatal(err)
}
log.Printf("title: %s", conf.Title)
log.Printf("Feature 1: %#v", conf.F1)
log.Printf("Feature 2: %#v", conf.F2)
}
注意 tomlData
以及它如何映射到 tomlConfig
结构。
使用推荐的 pkg BurntSushi/toml 解决了这个问题!! 我做了如下操作,它是代码的一部分。
[toml 示例]
[title]
enable = true
[title.clientinfo.12345]
distance = 30
some_id = 6
[Golang 示例]
type TitleClientInfo struct {
Distance int `toml:"distance"`
SomeId int `toml:"some_id"`
}
type Config struct {
Enable bool `toml:"enable"`
ClientInfo map[string]TitleClientInfo `toml:"clientinfo"`
}
var config Config
_, err := toml.Decode(string(d), &config)
然后,就可以如我所愿的使用了
config.ClientInfo[12345].Distance
谢谢!
2019 年的一个小更新 - 现在有 BurntSushi/toml 的更新替代品,具有更丰富的 API 来处理 .toml 文件:
pelletier/go-toml (and documentation)
例如有 config.toml
个文件(或在内存中):
[postgres]
user = "pelletier"
password = "mypassword"
除了使用 pelletier/go-toml 将整个事物常规编组和解组为预定义结构(您可以在接受的答案中看到)之外,您还可以查询单个值,如下所示:
config, err := toml.LoadFile("config.toml")
if err != nil {
fmt.Println("Error ", err.Error())
} else {
// retrieve data directly
directUser := config.Get("postgres.user").(string)
directPassword := config.Get("postgres.password").(string)
fmt.Println("User is", directUser, " and password is", directPassword)
// or using an intermediate object
configTree := config.Get("postgres").(*toml.Tree)
user := configTree.Get("user").(string)
password := configTree.Get("password").(string)
fmt.Println("User is", user, " and password is", password)
// show where elements are in the file
fmt.Printf("User position: %v\n", configTree.GetPosition("user"))
fmt.Printf("Password position: %v\n", configTree.GetPosition("password"))
// use a query to gather elements without walking the tree
q, _ := query.Compile("$..[user,password]")
results := q.Execute(config)
for ii, item := range results.Values() {
fmt.Println("Query result %d: %v", ii, item)
}
}
更新
还有 spf13/viper 适用于 .toml 配置文件(以及其他受支持的格式),但在许多情况下可能有点矫枉过正。
更新 2
Viper 并不是真正的 alternative (credits to @GoForth)。
使用解决方案 Viper 你可以在 JSON、TOML、YAML、HCL、INI 和其他文件中使用配置文件属性格式。
创建文件:
./config.toml
首次导入:
import (config "github.com/spf13/viper")
初始化:
config.SetConfigName("config")
config.AddConfigPath(".")
err := config.ReadInConfig()
if err != nil {
log.Println("ERROR", err.Error())
}
并获取值:
config.GetString("datatitle.12345.prop1")
config.Get("datatitle.12345.prop1").(int32)
我正在使用spf13/viper
第 3 包
Status | Project | Starts | Forks |
---|---|---|---|
Alive | spf13/viper | ||
Alive | BurntSushi/toml |
毒蛇的用法
我尝试用一个table把代码和配置文件的内容放在一起,但是很明显,编辑和最终的结果不符,所以放上图,希望它会让你更容易比较
package main
import (
"github.com/spf13/viper"
"log"
"os"
)
func main() {
check := func(err error) {
if err != nil {
panic(err)
}
}
myConfigPath := "test_config.toml"
fh, err := os.OpenFile(myConfigPath, os.O_RDWR, 0666)
check(err)
viper.SetConfigType("toml") // do not ignore
err = viper.ReadConfig(fh)
check(err)
// Read
log.Printf("%#v", viper.GetString("title")) // "my config"
log.Printf("%#v", viper.GetString("DataTitle.12345.prop1")) // "30"
log.Printf("%#v", viper.GetString("dataTitle.12345.prop1")) // "30" // case-insensitive
log.Printf("%#v", viper.GetInt("DataTitle.12345.prop1")) // 30
log.Printf("%#v", viper.GetIntSlice("feature1.userids")) // []int{456, 789}
// Write
viper.Set("database", "newuser")
viper.Set("owner.name", "Carson")
viper.Set("feature1.userids", []int{111, 222}) // overwrite
err = viper.WriteConfigAs(myConfigPath)
check(err)
}
title = "my config"
[datatitle]
[datatitle.12345]
prop1 = 30
[feature1]
userids = [456,789]
database = "newuser" # New
title = "my config"
[datatitle]
[datatitle.12345]
prop1 = 30
[feature1]
userids = [111,222] # Update
[owner] # New
name = "Carson"
我正在使用这个 [1] go-toml 库。
它非常适合我的使用。我写了这个 [2] go util 来使用 go-toml
处理 containerd config.toml 文件