Я новачок у програмуванні Go, і мені цікаво: що є кращим способом обробки параметрів конфігурації для програми Go (вид речі, для якого можна використовувати файли властивостей або ini- файли, в інших контекстах)?
Я новачок у програмуванні Go, і мені цікаво: що є кращим способом обробки параметрів конфігурації для програми Go (вид речі, для якого можна використовувати файли властивостей або ini- файли, в інших контекстах)?
Відповіді:
Формат JSON працював для мене досить добре. Стандартна бібліотека пропонує способи запису структури даних у відступі, тому вона досить читабельна.
Дивіться також цю нитку голанг-горіхів .
Переваги JSON полягають у тому, що він досить просто розбирає та читає / редагує людину / редагує, пропонуючи семантику для списків та відображень (що може стати досить зручним), що не стосується багатьох конфігураційних парсерів ini-типу.
Приклад використання:
conf.json :
{
"Users": ["UserA","UserB"],
"Groups": ["GroupA"]
}
Програма для зчитування конфігурації
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]
defer file.Close()
після перевірки відкритої помилки
Інший варіант - використовувати TOML , який є INI-подібним форматом, створеним Томом Престоном-Вернером. Я створив для нього аналізатор Go, який проходить випробування . Ви можете використовувати його, як і інші варіанти, запропоновані тут. Наприклад, якщо у вас є ці дані TOMLsomething.toml
Age = 198
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z
Потім ви можете завантажити його у свою програму Go з чимось подібним
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
}
Viper - це система управління конфігурацією golang, яка працює з JSON, YAML та TOML. Це виглядає досить цікаво.
Зазвичай я використовую JSON для складніших структур даних. Мінус полягає в тому, що ви легко отримуєте купу коду, щоб повідомити користувачеві, де була помилка, різні крайові випадки та що ні.
Що стосується базової конфігурації (ключі api, номери портів, ...), мені дуже вдало з пакетом gcfg . Він заснований на форматі git config.
З документації:
Приклад конфігурації:
; Comment line
[section]
name = value # Another comment
flag # implicit value for bool is true
Перехід:
type Config struct {
Section struct {
Name string
Flag bool
}
}
І код, необхідний для його читання:
var cfg Config
err := gcfg.ReadFileInto(&cfg, "myconfig.gcfg")
Він також підтримує значення зрізів, тому ви можете дозволити кілька разів вказувати ключ та інші приємні функції.
Просто використовуйте стандартні прапори Go with iniflags .
Стандартні прапори мають такі переваги:
Єдиний стандарт недоліків стандартних ігор - це проблеми управління, коли кількість прапорів, які використовуються у вашій програмі, стає занадто великою.
Iniflags елегантно вирішує цю проблему: просто змініть два рядки в основному пакеті, і це магічним чином отримує підтримку для читання значень прапора з ini-файлу. Прапори з ini-файлів можна змінити, передавши нові значення в командному рядку.
Докладніше див. Також https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE .
go test
не дає мені пропускати прапори), а конфігураційний файл не буде.
*FlagName = value
Я почав використовувати Gcfg який використовує файли, подібні до Ini. Це просто - якщо ви хочете чогось простого, це хороший вибір.
Ось код завантаження, який я використовую зараз, має налаштування за замовчуванням і дозволяє прапорці командного рядка (не показано), які замінюють деякі мої конфігурації:
package util
import (
"code.google.com/p/gcfg"
)
type Config struct {
Port int
Verbose bool
AccessLog string
ErrorLog string
DbDriver string
DbConnection string
DbTblPrefix string
}
type configFile struct {
Server Config
}
const defaultConfig = `
[server]
port = 8000
verbose = false
accessLog = -
errorLog = -
dbDriver = mysql
dbConnection = testuser:TestPasswd9@/test
dbTblPrefix =
`
func LoadConfiguration(cfgFile string, port int, verbose bool) Config {
var err error
var cfg configFile
if cfgFile != "" {
err = gcfg.ReadFileInto(&cfg, cfgFile)
} else {
err = gcfg.ReadStringInto(&cfg, defaultConfig)
}
PanicOnError(err)
if port != 0 {
cfg.Server.Port = port
}
if verbose {
cfg.Server.Verbose = true
}
return cfg.Server
}
подивіться на gonfig
// load
config, _ := gonfig.FromJson(myJsonFile)
// read with defaults
host, _ := config.GetString("service/host", "localhost")
port, _ := config.GetInt("service/port", 80)
test, _ := config.GetBool("service/testing", false)
rate, _ := config.GetFloat("service/rate", 0.0)
// parse section into target structure
config.GetAs("service/template", &template)
https://github.com/spf13/viper та https://github.com/zpatrick/go-config - це досить непогані бібліотеки для файлів конфігурації.
Використовуйте toml, як ця стаття. Читання конфігураційних файлів вперед
Я написав просту бібліотеку ini config у голанг.
безпечна програма, проста у використанні
package cfg
import (
"testing"
)
func TestCfg(t *testing.T) {
c := NewCfg("test.ini")
if err := c.Load() ; err != nil {
t.Error(err)
}
c.WriteInt("hello", 42)
c.WriteString("hello1", "World")
v, err := c.ReadInt("hello", 0)
if err != nil || v != 42 {
t.Error(err)
}
v1, err := c.ReadString("hello1", "")
if err != nil || v1 != "World" {
t.Error(err)
}
if err := c.Save(); err != nil {
t.Error(err)
}
}
=================== Оновити ========================
Нещодавно мені потрібен парсер INI з підтримкою розділу, і я пишу простий пакет:
github.com/c4pt0r/cfg
Ви можете проаналізувати INI, наприклад, використовуючи пакет "flag":
package main
import (
"log"
"github.com/c4pt0r/ini"
)
var conf = ini.NewConf("test.ini")
var (
v1 = conf.String("section1", "field1", "v1")
v2 = conf.Int("section1", "field2", 0)
)
func main() {
conf.Parse()
log.Println(*v1, *v2)
}
Можливо, вас також зацікавить go-libucl , набір зв'язків Go для UCL, універсальної мови конфігурації. UCL трохи схожий на JSON, але з кращою підтримкою для людей: він підтримує коментарі та зручні для читання людині конструкції, такі як мультиплікатори SI (10k, 40M тощо) і має трохи менше котлован (наприклад, цитати навколо клавіш). Це насправді досить близько до формату файлу конфігурації nginx, якщо ви вже знайомі з цим.
Я погоджуюся з немо, і я написав невеликий інструмент, щоб зробити це справді легко.
bitbucket.org/gotamer/cfg - це конфігураційний пакет json
Див. Приклад
Я спробував JSON. Це спрацювало. Але я ненавиджу створювати структуру точних полів і типів, які я можу встановити. Для мене це був біль. Я помітив, що це метод, який застосовують усі параметри конфігурації, які я міг знайти. Можливо, мій досвід динамічних мов робить мене сліпим від переваг такої багатослівності. Я створив новий простий формат конфігураційного файлу та більш динамічну ліштва для його читання.
https://github.com/chrisftw/ezconf
Я досить новачок у світі Go, тому, можливо, це не шлях. Але це працює, він досить швидкий і супер простий у використанні.