欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang使用viper加載配置文件實(shí)現(xiàn)自動反序列化到結(jié)構(gòu)

 更新時(shí)間:2023年08月28日 08:56:27   作者:莫大  
這篇文章主要為大家介紹了golang使用viper加載配置文件實(shí)現(xiàn)自動反序列化到結(jié)構(gòu)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

  • golang使用 viper 無需設(shè)置 mapstructure tag 根據(jù)配置文件后綴 自動返序列化到結(jié)構(gòu)
  • 解決結(jié)構(gòu)有下劃線的字段解析不成功問題

viper 正常加載配置文件

golang viper 其中可以用來 查找、加載和反序列化JSON、TOML、YAML、HCL、INI、envfile和格式的配置文件

配置文件 test_toml.toml

http_addr = ":8082"
grpc_addr = ":8083"
jaeger_url= "http://localhost:14268/api/traces"
tracing= true

golang代碼

type ConfigTest struct {
    HttpAddr  string `json:"http_addr" toml:"http_addr" yaml:"http_addr"`
    GrpcAddr  string `json:"grpc_addr" toml:"grpc_addr" yaml:"grpc_addr"`
    JaegerUrl string `json:"jaeger_url" toml:"jaeger_url" yaml:"jaeger_url" mapstructure:"jaeger_url"`
    Tracing   bool   `toml:"tracing"  json:"tracing" yaml:"tracing" ` // opentelemetry tracing
}

// jaeger 加載配置文件
func TestSourceFile_Unmarshal(t *testing.T) {
    filePath := "./test_toml.toml"
    viper.SetConfigFile(filePath)
    if err := viper.ReadInConfig(); err != nil {
        t.Error(err)
    }

    c := &ConfigTest{}
    if err := viper.Unmarshal(c); err != nil {
        t.Error(err)
    }
    logger.Infow("Unmarshal file sucess", "v", c)
}

打印返序列化的配置結(jié)構(gòu)

{"level":"info","ts":"2023-08-27T21:35:27.041+0800","caller":"config/source_file_test.go:31","msg":"Unmarshal file sucess","v":{"http_addr":"","grpc_addr":"","jaeger_url":"http://localhost:14268/api/traces","tracing":true}}

可以看到帶下劃線的字段,不加 mapstructure 標(biāo)簽,是不會反序列化

不加 mapstructure tag實(shí)現(xiàn)自動反序列化

查看viper Unmarshal 代碼

func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
    return decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
}
func decode(input interface{}, config *mapstructure.DecoderConfig) error {
    decoder, err := mapstructure.NewDecoder(config)
    if err != nil {
        return err
    }
    return decoder.Decode(input)
}
func NewDecoder(config *DecoderConfig) (*Decoder, error) {
    if config.TagName == "" {
        config.TagName = "mapstructure"
    }
    // ...
}
  • 從代碼看出 Viper使用的是 github.com/mitchellh/mapstructure來解析值
  • mapstructure 用于將通用的map[string]interface{}解碼到對應(yīng)的 Go 結(jié)構(gòu)體中
  • 默認(rèn)情況下,mapstructure 使用結(jié)構(gòu)體中字段的名稱做這個(gè)映射,不區(qū)分大小寫,比如 Name 字段可以映射到 name、NAME、NaMe 等等
  • 如果沒有指定 tagName ,則默認(rèn)為 mapstructure,這也是為什么帶下劃線的字段不加 mapstructure 標(biāo)簽無法解析的原因
  • viper 中Unmarshal的第二個(gè)參數(shù)是可以指定 DecoderConfigOption ,從而可以指定 tagName

viper根據(jù)文類型件自動解碼到結(jié)構(gòu)

  • 讀取文件后綴比如 toml
  • 根據(jù)后綴設(shè)置 tagName
  • 調(diào)用 viper.Unmarshal解析
func TestSourceFile_Unmarshal1(t *testing.T) {
    filePath := "./test_toml.toml"
    c := &ConfigTest{}
    if err := viperUnmarshal(c, filePath); err != nil {
        t.Error(err)
    }
    logger.Infow("Unmarshal file sucess", "v", c)
}
func viperUnmarshal(v interface{}, configPath string) error {
    var tagName string
    ext := filepath.Ext(configPath)
    if len(ext) > 1 {
        tagName = ext[1:]
    }
    // set decode tag_name, default is mapstructure
    decoderConfigOption := func(c *mapstructure.DecoderConfig) {
        c.TagName = tagName
    }
    cViper := viper.New()
    cViper.SetConfigFile(configPath)
    if err := cViper.ReadInConfig(); err != nil {
        return err
    }
    return cViper.Unmarshal(v, decoderConfigOption)
}

 結(jié)果:

{"level":"info","ts":"2023-08-27T21:35:34.553+0800","caller":"config/source_file_test.go:40","msg":"Unmarshal file sucess","v":{"http_addr":":8082","grpc_addr":":8083","jaeger_url":"http://localhost:14268/api/traces","tracing":true}}

我已將viper加載配置集成進(jìn)自己的項(xiàng)目,完整example 代碼可以查看 source_file_test.go

以上就是golang 使用 viper 加載配置文件 自動反序列化到結(jié)構(gòu)的詳細(xì)內(nèi)容,更多關(guān)于golang viper 加載配置文件 自動反序列化到結(jié)構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語言實(shí)現(xiàn)逐行讀取和寫入文件詳解

    Go語言實(shí)現(xiàn)逐行讀取和寫入文件詳解

    這篇文章主要介紹了如何使用go語言實(shí)現(xiàn)從輸入文件中讀取每行數(shù)據(jù),然后將每行字段組合成SQL插入腳本,然后逐行寫入另外一個(gè)空白文件中,有需要的可以參考下
    2024-01-01
  • Golang?WorkerPool線程池并發(fā)模式示例詳解

    Golang?WorkerPool線程池并發(fā)模式示例詳解

    這篇文章主要為大家介紹了Golang?WorkerPool線程池并發(fā)模式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • vscode配置go開發(fā)環(huán)境的實(shí)戰(zhàn)過程

    vscode配置go開發(fā)環(huán)境的實(shí)戰(zhàn)過程

    vscode配置go的開發(fā)環(huán)境很簡單,下面這篇文章主要給大家介紹了關(guān)于vscode配置go開發(fā)環(huán)境的實(shí)戰(zhàn)過程,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Golang?range?slice?與range?array?之間的區(qū)別

    Golang?range?slice?與range?array?之間的區(qū)別

    這篇文章主要介紹了Golang?range?slice?與range?array?之間的區(qū)別,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-07-07
  • go語言template用法實(shí)例

    go語言template用法實(shí)例

    這篇文章主要介紹了go語言template用法,實(shí)例分析了template的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Go項(xiàng)目分層下的最佳error處理方式分享

    Go項(xiàng)目分層下的最佳error處理方式分享

    這篇文章主要來和大家一起探討?Go?項(xiàng)目分層下的最佳?error?處理方式,準(zhǔn)備好了嗎?準(zhǔn)備一杯你最喜歡的飲料或茶,隨著本文一探究竟吧
    2023-06-06
  • Golang算法之田忌賽馬問題實(shí)現(xiàn)方法分析

    Golang算法之田忌賽馬問題實(shí)現(xiàn)方法分析

    這篇文章主要介紹了Golang算法之田忌賽馬問題實(shí)現(xiàn)方法,結(jié)合具體實(shí)例形式分析了基于Go語言的田忌賽馬問題原理與算法實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-02-02
  • Go語言中匿名嵌套和類型嵌套的區(qū)別解析

    Go語言中匿名嵌套和類型嵌套的區(qū)別解析

    在Go語言中,匿名嵌套結(jié)構(gòu)體和與類型同名的嵌套結(jié)構(gòu)體不是完全等價(jià)的,它們有一些重要的區(qū)別,這篇文章主要介紹了Go語言中匿名嵌套和類型嵌套的區(qū)別,需要的朋友可以參考下
    2023-09-09
  • 一文教你Golang如何正確關(guān)閉通道

    一文教你Golang如何正確關(guān)閉通道

    Go在通道這一塊,沒有內(nèi)置函數(shù)判斷通道是否已經(jīng)關(guān)閉,也沒有可以直接獲取當(dāng)前通道數(shù)量的方法,因此如果對通道進(jìn)行了錯(cuò)誤的使用,將會直接引發(fā)系統(tǒng)?panic,這是一件很危險(xiǎn)的事情,下面我們就來學(xué)習(xí)一下如何正確關(guān)閉通道吧
    2023-10-10
  • go?mod?tidy報(bào)錯(cuò)解決方法詳解

    go?mod?tidy報(bào)錯(cuò)解決方法詳解

    這篇文章主要為大家介紹了go?mod?tidy報(bào)錯(cuò)解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12

最新評論