golang使用viper加载配置文件实现自动反序列化到结构

 更新时间:2023年08月28日 08:56:27   作者:莫大  
这篇文章主要为大家介绍了golang使用viper加载配置文件实现自动反序列化到结构示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

  • golang使用 viper 无需设置 mapstructure tag 根据配置文件后缀 自动返序列化到结构
  • 解决结构有下划线的字段解析不成功问题

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)
}

打印返序列化的配置结构

{"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 标签,是不会反序列化

不加 mapstructure tag实现自动反序列化

查看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{}解码到对应的 Go 结构体中
  • 默认情况下,mapstructure 使用结构体中字段的名称做这个映射,不区分大小写,比如 Name 字段可以映射到 name、NAME、NaMe 等等
  • 如果没有指定 tagName ,则默认为 mapstructure,这也是为什么带下划线的字段不加 mapstructure 标签无法解析的原因
  • viper 中Unmarshal的第二个参数是可以指定 DecoderConfigOption ,从而可以指定 tagName

viper根据文类型件自动解码到结构

  • 读取文件后缀比如 toml
  • 根据后缀设置 tagName
  • 调用 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)
}

 结果:

{"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加载配置集成进自己的项目,完整example 代码可以查看 source_file_test.go

以上就是golang 使用 viper 加载配置文件 自动反序列化到结构的详细内容,更多关于golang viper 加载配置文件 自动反序列化到结构的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言异常处理error、panic、recover的使用

    Go语言异常处理error、panic、recover的使用

    GO语言中引入的异常的处理方式为error、panic、recover ,本文主要介绍了Go语言异常处理error、panic、recover的使用,感兴趣的可以了解一下
    2024-08-08
  • 用Go+Vue.js快速搭建一个Web应用(初级demo)

    用Go+Vue.js快速搭建一个Web应用(初级demo)

    这篇文章主要介绍了用Go+Vue.js快速搭建一个Web应用(初级demo),本文给大家介绍的非常详细,具有参考借鉴价值,需要的朋友参考下吧
    2017-11-11
  • golang中接口对象的转型两种方式

    golang中接口对象的转型两种方式

    这篇文章主要介绍了golang中接口对象的转型方式,大家都知道接口对象的转型有两种方式,文中通过示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2021-10-10
  • Go项目的目录结构详解

    Go项目的目录结构详解

    这篇文章主要介绍了Go项目的目录结构,对基础目录做了讲解,对项目开发中的其它目录也一并做了介绍,需要的朋友可以参考下
    2014-10-10
  • Go整合ElasticSearch的示例代码

    Go整合ElasticSearch的示例代码

    这篇文章主要介绍了Go整合ElasticSearch的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • 一文详解Go中方法接收器的选择

    一文详解Go中方法接收器的选择

    许多 Go 初学者在方法接收器的选择上可能会感到困惑,不知道该选择值接收器还是指针接收器。本文将会对方法接收器进行介绍,并给出如何选择正确方法接收器的指导建议,希望对大家有所帮助
    2023-04-04
  • 深入理解 Go 中的字符串

    深入理解 Go 中的字符串

    这篇文章主要介绍了深入理解 Go 中的字符串,在编程语言中,字符串发挥着重要的角色。字符串背后的数据结构一般有两种类型,一种在编译时指定长度不能修改,一种具有动态的长度可以修改,下文更多相关资料需要的小伙伴可以参考一下
    2022-05-05
  • 浅析Go语言中的同步与异步处理

    浅析Go语言中的同步与异步处理

    在开发过程中,当需要同时处理多个操作时,开发者经常面临同步和异步两种处理方式的选择,下面小编就来和大家详细介绍一下Go语言中的同步与异步处理吧
    2023-11-11
  • Golang的命名规范及最佳实践(推荐!)

    Golang的命名规范及最佳实践(推荐!)

    这篇文章主要给大家介绍了关于Golang的命名规范及最佳实践的相关资料,命名规则涉及变量、常量、全局函数、结构、接口、方法等的命名,文中介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • Golang设计模式之外观模式讲解和代码示例

    Golang设计模式之外观模式讲解和代码示例

    外观是一种结构型设计模式, 能为复杂系统、 程序库或框架提供一个简单 (但有限) 的接口,这篇文章就给大家详细介绍一下Golang的外观模式,文中有详细的代码示例,具有一定的参考价值,需要的朋友可以参考下
    2023-06-06

最新评论