How to handle configuration in Go [closed]

2019-01-20 21:27发布

I'm new at Go programming, and I'm wondering: what is the preferred way to handle configuration parameters for a Go program (the kind of stuff one might use properties files or ini files for, in other contexts)?

13条回答
smile是对你的礼貌
2楼-- · 2019-01-20 21:39

I tried JSON. It worked. But I hate having to create the struct of the exact fields and types I might be setting. To me that was a pain. I noticed it was the method used by all the configuration options I could find. Maybe my background in dynamic languages makes me blind to the benefits of such verboseness. I made a new simple config file format, and a more dynamic-ish lib for reading it out.

https://github.com/chrisftw/ezconf

I am pretty new to the Go world, so it might not be the Go way. But it works, it is pretty quick, and super simple to use.

Pros

  • Super simple
  • Less code

Cons

  • No Arrays or Map types
  • Very flat file format
  • Non-standard conf files
  • Does have a little convention built-in, which I now if frowned upon in general in Go community. (Looks for config file in the config directory)
查看更多
太酷不给撩
3楼-- · 2019-01-20 21:40

The JSON format worked for me quite well. The standard library offers methods to write the data structure indented, so it is quite readable.

See also this golang-nuts thread.

The benefits of JSON are that it is fairly simple to parse and human readable/editable while offering semantics for lists and mappings (which can become quite handy), which is not the case with many ini-type config parsers.

Example usage:

conf.json:

{
    "Users": ["UserA","UserB"],
    "Groups": ["GroupA"]
}

Program to read the configuration

import (
    "encoding/json"
    "os"
    "fmt"
)

type Configuration struct {
    Users    []string
    Groups   []string
}

file, _ := os.Open("conf.json")
defer file.Close()
decoder := json.NewDecoder(file)
configuration := Configuration{}
err := decoder.Decode(&configuration)
if err != nil {
  fmt.Println("error:", err)
}
fmt.Println(configuration.Users) // output: [UserA, UserB]
查看更多
女痞
4楼-- · 2019-01-20 21:42

Another option is to use TOML, which is an INI-like format created by Tom Preston-Werner. I built a Go parser for it that is extensively tested. You can use it like other options proposed here. For example, if you have this TOML data in something.toml

Age = 198
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z

Then you can load it into your Go program with something like

type Config struct {
    Age int
    Cats []string
    Pi float64
    Perfection []int
    DOB time.Time
}

var conf Config
if _, err := toml.DecodeFile("something.toml", &conf); err != nil {
    // handle error
}
查看更多
beautiful°
5楼-- · 2019-01-20 21:42

I usually use JSON for more complicated data structures. The downside is that you easily end up with a bunch of code to tell the user where the error was, various edge cases and what not.

For base configuration (api keys, port numbers, ...) I've had very good luck with the gcfg package. It is based on the git config format.

From the documentation:

Sample config:

; Comment line
[section]
name = value # Another comment
flag # implicit value for bool is true

Go struct:

type Config struct {
    Section struct {
            Name string
            Flag bool
    }
}

And the code needed to read it:

var cfg Config
err := gcfg.ReadFileInto(&cfg, "myconfig.gcfg")

It also supports slice values, so you can allow specifying a key multiple times and other nice features like that.

查看更多
贪生不怕死
6楼-- · 2019-01-20 21:42

https://github.com/spf13/viper and https://github.com/zpatrick/go-config are a pretty good libraries for configuration files.

查看更多
干净又极端
7楼-- · 2019-01-20 21:43
登录 后发表回答