在 golang 中解组 json 时如何跳过现有字段?

我使用jsonfile 来配置我的程序参数,并使用flagpackage 来配置相同的参数。


当一些参数同时被json文件解析flag时,我希望使用通过flag.


麻烦的是json文件路径也是通过.解析出来的flag。调用后可以得到json路径flag.parse(),但是参数也被解析了,那么Unmarshaljson会覆盖flag解析的参数。


示例 JSON:


{

    "opt1": 1,

    "opt2": "hello"

}

示例代码:


var Config = struct {

    Opt1 int    `json:"opt1"`

    Opt2 string `json:"opt2"`

}{

    Opt1: 0,

    Opt2: "none",

}


func main() {


    // parse config file path

    var configFile string

    flag.StringVar(&configFile, "config", "", "config file path")


    // parse options

    flag.IntVar(&Config.Opt1, "opt1", Config.Opt1, "")

    flag.StringVar(&Config.Opt2, "opt2", Config.Opt2, "")


    // parse flags

    flag.Parse()


    // load config options from config.json file

    if configFile != "" {

        if data, err := ioutil.ReadFile(configFile); err != nil {

            fmt.Printf("read config file error: %v\n", err)

        } else if err = json.Unmarshal(data, &Config); err != nil {

            fmt.Printf("parse config file error: %v\n", err)

        }

    }


    fmt.Printf("%+v", Config)

}

程序示例输出:

./foo.exe -opt2 world

out:{Opt1:0 Opt2:world}


./foo.exe -config config.json

出去:{Opt1:1 Opt2:hello}


./foo.exe -config config.json -opt2 world

真正的出局:{Opt1:1 Opt2:hello}

希望出局:{Opt1:1 Opt2:world}


繁花如伊
浏览 172回答 1
1回答

汪汪一只猫

一个简单的解决方案是首先解析 JSON 配置文件,完成后,再继续解析 CLI 参数。问题在于 JSON 配置文件也是 CLI arg。flag.Parse()最简单的解决方案是在解析配置文件后再次调用:// load config options from config.json fileif configFile != "" {    if data, err := ioutil.ReadFile(configFile); err != nil {        fmt.Printf("read config file error: %v\n", err)    } else if err = json.Unmarshal(data, &Config); err != nil {        fmt.Printf("parse config file error: %v\n", err)    }    // parse flags again to have precedence    flag.Parse()}第二个flag.Parse()将覆盖并因此优先于来自 JSON 文件的数据。加上这个,运行./foo.exe -config config.json -opt2 world输出将是你想要的:{Opt1:1 Opt2:world}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go