9

作为标题,我想知道如何使用 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

提前致谢!

4

6 回答 6

11

首先获取 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结构。

在https://github.com/BurntSushi/toml查看更多示例

于 2015-12-16T09:46:45.317 回答
5

2019 年的一个小更新 - 现在有更新的BurntSushi/toml替代方案,具有更丰富的 API 来处理.toml文件:

制粒机/go-toml(和文档

例如有config.toml文件(或在内存中):

[postgres]
user = "pelletier"
password = "mypassword"

除了使用pellier / 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 并不是真正的替代品(归功于@GoForth)。

于 2019-09-21T00:24:32.863 回答
4

使用推荐的 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

谢谢!

于 2015-12-18T03:48:48.750 回答
2

使用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)

文档:https ://github.com/spf13/viper

例如:https ://repl.it/@DarlanD/Viper-Examples#main.go

于 2020-04-14T13:39:58.830 回答
0

我正在使用spf13/viper

第三包

地位 项目 开始 叉子
spf13/毒蛇 星星 星星
BurntSushi/toml 星星 星星

毒蛇的用法

我试着用一个表格把代码和配置文件的内容放在一起,但是很明显,编辑的结果和最终的结果不符,所以我把图放上来,希望方便大家比较

在此处输入图像描述


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"

于 2021-02-09T18:07:56.280 回答
0

我正在使用这个 [1] go-toml 库。

它非常适合我的使用。我写了这个 [2] go util 来使用 go-toml 处理 containerd config.toml 文件

[1] https://github.com/pelletier/go-toml

[2] https://github.com/prakashmirji/toml-configer

于 2021-09-03T10:00:37.430 回答