在我们开发过程中,像数据库信息、邮件配置和其他的第三方服务密钥等这些固定的信息都会写在配置文件中,而配置文件又有多种表现形式和格式,有 JSON, TOML, YAML各种格式,而且测试环境,开发环境和生产环境用的配置文件也不是同一份。
我们需要一个go 库可以做这件事!
github: https://github.com/spf13/viper
viper
美: [ˈvaɪpər]
英: [ˈvaɪpə®]
n. 蝰蛇(一种小毒蛇);毒如蛇蝎的人;险恶的人
网络 冥界亚龙;道奇蝰蛇;蝮蛇
Viper是Go应用程序的完整配置解决方案,
viper 支持Yaml、Json、 TOML、HCL 等格式,读取非常的方便。
Viper can be thought of as a registry for all of your applications configuration needs.
Viper可以被认为是您的所有应用程序配置需求的注册表
Viper
参考URL: https://www.cnblogs.com/zc110/articles/14603870.html
在构建现代应用程序时,你无需担心配置文件格式;你想要专注于构建出色的软件。Viper的出现就是为了在这方面帮助你的。
Viper能够为你执行下列操作:
Viper会按照下面的优先级。每个项目的优先级都高于它下面的项目:
Viper 可以从不同的位置读取配置,不同位置的配置具有不同的优先级,高优先级的配置会覆盖低优先级相同的配置,按优先级从高到低排列如下:
func init(){
viper.SetConfigFile("hello.toml")//文件名
viper.Set("Address","0.0.0.0:9090")//统一把Key处理成小写 Address->address
err := viper.WriteConfig()//写入文件
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
}
运行一下,会发现当前目录会出现一个hello.toml的文件
相对于写入配置文件的操作。
viper.SetConfigFile("hello.toml")
err := viper.ReadInConfig() // 会查找和读取配置文件
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
Address = viper.GetString("Address")
//key取Address或者address都能取到值,反正viper转成小写处理
fmt.Println(Address)
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("配置发生变更:", e.Name)
})
不建议在实际开发中使用热加载功能,因为即使配置热加载了,程序中的代码也不一定会热加载。例如:修改了服务监听端口,但是服务没有重启,这时候服务还是监听在老的端口上,会造成不一致。
viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
Viper 支持 Pflag 包,能够绑定 key 到 Flag。我们可以将标志绑定到 Viper,这样就可以使用 viper.Get() 获取标志的值。
绑定单个标志
viper.BindPFlag("token", pflag.Lookup("token"))
还可以绑定一组现有的 pflags(pflag.FlagSet):
viper.BindPFlags(pflag.CommandLine)
注意:工作中,这个常用到,一般都是命令行优先与配置文件,这样配置统一就是viper来管理,最后一次反序列化到我们的配置实例中。
Viper 可以支持将所有或特定的值解析到结构体、map 等。可以通过两个函数来实现:
Unmarshal(rawVal interface{}) error
UnmarshalKey(key string, rawVal interface{}) error
type config struct {
Port int
Name string
PathMap string `mapstructure:"path_map"`
}
var C config
err := viper.Unmarshal(&C)
if err != nil {
t.Fatalf("unable to decode into struct, %v", err)
}
Viper 在后台使用 github.com/mitchellh/mapstructure 来解析值,其默认情况下使用mapstructure tags。当我们需要将 Viper 读取的配置反序列到我们定义的结构体变量中时,一定要使用 mapstructure tags。
注意:工作中,这个常用到,这块就是把我们从配置文件中读到内容,反序列化特定的struct实例,方便代码使用。
Viper
参考URL: https://www.cnblogs.com/zc110/articles/14603870.html