1. 程式人生 > >golang同時使用命令列引數和配置檔案

golang同時使用命令列引數和配置檔案

golang同時使用命令列引數和配置檔案

[toc]

之前使用過spring-boot框架,在配置引數傳遞上可以使用配置檔案--applications.yml,也可以使用命令列引數來覆蓋,用起來非常方便。那麼golang有沒有類似功能呢?經過一番研究發現並沒有殺手級的第三方package,因此就有以下自己搗鼓出來的方法。

Config

type Config struct{
	Username string
	Password string
}

func (c *Config)Parse(){
	flag.StringVar(&c.Username,"username",c.Username,"the username for login")
	flag.StringVar(&c.Password,"password",c.Password,"the password for login")
	flag.Parse()
}

func NewConfig() *Config{
	return &Config{
		Username:"default_user",
		Password:"default_password",
	}
}

使用

package main
import (
	"os"
	"github.com/BurntSushi/toml"
)
var config *Config
func init(){
	config = NewConfig()
	if _,err:= os.Stat("config.toml");!os.IsNotExist(err){
		if _,err :=  toml.DecodeFile("config.toml", config); err != nil {
			panic(err)
		}
	}
	config.Parse()
}

注意

以上方案事通過解析配置檔案,給flag設定預設值,因此有三個值得注意的地方:

  • 必須先進行toml解析,再進行Parse操作,以便讓命令列引數覆蓋配置檔案引數;
  • 由於flag.Parse()是全域性的函式,其他的引數必須在呼叫config.Parse()之前定義;
  • 無法使用命令列引數來傳遞自定義配置檔案路徑。

使用kingpin

除了標準庫中的flag也可以用第三方庫,以下以kingpin為例:

func (c *Config)Parse(){
	kingpin.Flag("username","the username for login").Default(c.Username).Short('u').StringVar(&c.Username)
	kingpin.Flag("password","the password for login").Default(c.Password).Short('p').StringVar(&c.Password)
	kingpi