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 加载配置文件 自动反序列化到结构的资料请关注脚本之家其它相关文章!

相关文章

  • golang使用tail实现追踪文件变更

    golang使用tail实现追踪文件变更

    这篇文章主要为大家介绍了golang如何借助 github.com/hpcloud/tail ,实现实时追踪文件变更,达到类似shell命令tail -f的效果,感兴趣的小伙伴可以了解一下
    2023-08-08
  • golang实践-第三方包为私有库的配置方案

    golang实践-第三方包为私有库的配置方案

    这篇文章主要介绍了golang实践-第三方包为私有库的配置方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • Golang Recover处理错误原理解析

    Golang Recover处理错误原理解析

    Golang 中的 recover 是一个鲜为人知但非常有趣和强大的功能,让我们看看它是如何工作的,以及在 Outreach.io 中如何利用它来处理 Kubernetes 中的错误
    2023-12-12
  • GoLang unsafe包详细讲解

    GoLang unsafe包详细讲解

    从golang的定义来看,unsafe 是类型安全的操作。顾名思义,它应该非常谨慎地使用; unsafe可能很危险,但也可能非常有用。例如,当使用系统调用和Go结构必须具有与C结构相同的内存布局时,您可能别无选择,只能使用unsafe
    2022-10-10
  • golang中bufio.SplitFunc的深入理解

    golang中bufio.SplitFunc的深入理解

    这篇文章主要给大家介绍了关于golang中bufio.SplitFunc的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用golang具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-10-10
  • Go Web框架gin的入门教程

    Go Web框架gin的入门教程

    本篇文章主要介绍了Go Web框架gin的入门教程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • golang中拿slice当queue和拿list当queue使用分析

    golang中拿slice当queue和拿list当queue使用分析

    这篇文章主要为大家介绍了golang 中拿slice当queue和拿list当queue使用分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • 一文了解Go语言的并发特性

    一文了解Go语言的并发特性

    本文主要介绍了一文了解Go语言的并发特性,通过轻量级线程、通道及选择语句,使得并发编程变得既简单又高效,下面就来具体了解一下如何使用,感兴趣的可以了解一下
    2024-02-02
  • Golang自旋锁的相关介绍

    Golang自旋锁的相关介绍

    自旋锁是指当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程将循环等待,然后不断地判断是否能够被成功获取,知直到获取到锁才会退出循环
    2022-10-10
  • Go语言映射内部实现及基础功能实战

    Go语言映射内部实现及基础功能实战

    这篇文章主要为大家介绍了Go语言映射的内部实现和基础功能实战,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2022-03-03

最新评论