Tôi mới tham gia lập trình Go và tôi tự hỏi: cách ưu tiên để xử lý các tham số cấu hình cho chương trình Go (loại nội dung nào người ta có thể sử dụng tệp thuộc tính hoặc tệp ini cho, trong các ngữ cảnh khác)?
Tôi mới tham gia lập trình Go và tôi tự hỏi: cách ưu tiên để xử lý các tham số cấu hình cho chương trình Go (loại nội dung nào người ta có thể sử dụng tệp thuộc tính hoặc tệp ini cho, trong các ngữ cảnh khác)?
Câu trả lời:
Các JSON định dạng làm việc cho tôi khá tốt. Thư viện chuẩn cung cấp các phương thức để viết cấu trúc dữ liệu thụt vào, vì vậy nó khá dễ đọc.
Xem thêm chủ đề golang-hạt này .
Lợi ích của JSON là khá đơn giản để phân tích cú pháp và có thể đọc / chỉnh sửa được con người trong khi cung cấp ngữ nghĩa cho danh sách và ánh xạ (có thể trở nên khá tiện dụng), điều này không xảy ra với nhiều trình phân tích cấu hình kiểu ini.
Ví dụ sử dụng:
conf.json :
{
"Users": ["UserA","UserB"],
"Groups": ["GroupA"]
}
Chương trình đọc cấu hình
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()
sau khi kiểm tra lỗi mở
Một tùy chọn khác là sử dụng TOML , đây là định dạng giống INI được tạo bởi Tom Preston-Werner. Tôi đã xây dựng một trình phân tích cú pháp Go cho nó được thử nghiệm rộng rãi . Bạn có thể sử dụng nó như các tùy chọn khác được đề xuất ở đây. Ví dụ: nếu bạn có dữ liệu TOML này trongsomething.toml
Age = 198
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z
Sau đó, bạn có thể tải nó vào chương trình Go của mình với nội dung như
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 là một hệ thống quản lý cấu hình golang hoạt động với JSON, YAML và TOML. Có vẻ khá thú vị.
Tôi thường sử dụng JSON cho các cấu trúc dữ liệu phức tạp hơn. Nhược điểm là bạn dễ dàng kết thúc với một loạt mã để báo cho người dùng biết lỗi ở đâu, các trường hợp cạnh khác nhau và những gì không.
Đối với cấu hình cơ sở (khóa api, số cổng, ...) Tôi đã rất may mắn với gói gcfg . Nó dựa trên định dạng cấu hình git.
Từ tài liệu:
Cấu hình mẫu:
; Comment line
[section]
name = value # Another comment
flag # implicit value for bool is true
Đi cấu trúc:
type Config struct {
Section struct {
Name string
Flag bool
}
}
Và mã cần thiết để đọc nó:
var cfg Config
err := gcfg.ReadFileInto(&cfg, "myconfig.gcfg")
Nó cũng hỗ trợ các giá trị lát, vì vậy bạn có thể cho phép chỉ định một khóa nhiều lần và các tính năng hay khác như thế.
Chỉ cần sử dụng cờ đi tiêu chuẩn với iniflags .
Cờ cờ tiêu chuẩn có những lợi ích sau:
Các cờ cờ tiêu chuẩn hạn chế duy nhất có - là các vấn đề về quản lý khi số lượng cờ được sử dụng trong ứng dụng của bạn trở nên quá lớn.
Iniflags giải quyết vấn đề này một cách tao nhã: chỉ cần sửa đổi hai dòng trong gói chính của bạn và nó sẽ hỗ trợ một cách kỳ diệu cho việc đọc các giá trị cờ từ tệp ini. Cờ từ các tệp ini có thể được ghi đè bằng cách chuyển các giá trị mới trong dòng lệnh.
Xem thêm https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE để biết chi tiết.
go test
không cho phép tôi chuyển cờ) trong khi tệp cấu hình sẽ không.
*FlagName = value
Tôi đã bắt đầu sử dụng Gcfg sử dụng các tệp giống như Ini. Thật đơn giản - nếu bạn muốn một cái gì đó đơn giản, đây là một lựa chọn tốt.
Đây là mã tải tôi hiện đang sử dụng, có cài đặt mặc định và cho phép cờ dòng lệnh (không hiển thị) ghi đè lên một số cấu hình của tôi:
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
}
có một cái nhìn tại 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 và https://github.com/zpatrick/go-config là một thư viện khá tốt cho các tệp cấu hình.
Sử dụng toml như bài viết này Đọc tập tin cấu hình theo cách đi
Tôi đã viết một thư viện cấu hình ini đơn giản trong golang.
goroutine an toàn, dễ sử dụng
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)
}
}
=================== Cập nhật =======================
Gần đây tôi cần một trình phân tích cú pháp INI với phần hỗ trợ và tôi viết một gói đơn giản:
github.com/c4pt0r/cfg
bạn có thể phân tích INI như sử dụng gói "cờ":
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)
}
Bạn cũng có thể quan tâm đến go-libucl , một tập hợp các ràng buộc Go cho UCL, Ngôn ngữ cấu hình phổ quát. UCL hơi giống JSON, nhưng với sự hỗ trợ tốt hơn cho con người: nó hỗ trợ các bình luận và các cấu trúc có thể đọc được của con người như hệ số nhân SI (10k, 40M, v.v.) và có một ít luồn lách hơn (ví dụ, trích dẫn xung quanh các phím). Nó thực sự khá gần với định dạng tệp cấu hình nginx, nếu bạn đã quen với điều đó.
Tôi đồng ý với nemo và tôi đã viết một công cụ nhỏ để làm cho tất cả thực sự dễ dàng.
bitbucket.org/gotamer/cfg là gói cấu hình json
Xem doc.go cho một ví dụ
Tôi đã thử JSON. Nó đã làm việc. Nhưng tôi ghét phải tạo cấu trúc của các trường và loại chính xác mà tôi có thể đang thiết lập. Đối với tôi đó là một nỗi đau. Tôi nhận thấy đó là phương pháp được sử dụng bởi tất cả các tùy chọn cấu hình mà tôi có thể tìm thấy. Có lẽ nền tảng của tôi trong các ngôn ngữ năng động làm cho tôi mù quáng về lợi ích của tính dài dòng như vậy. Tôi đã tạo một định dạng tệp cấu hình đơn giản mới và một lib-ish động hơn để đọc nó.
https://github.com/chrisftw/ezconf
Tôi khá mới mẻ với thế giới Go, vì vậy nó có thể không phải là con đường Go. Nhưng nó hoạt động, nó khá nhanh và sử dụng siêu đơn giản.