赞
踩
import "github.com/spf13/viper"
func main() {
// 设置当前的主文件目录, main.go 所在的位置
viper.SetDefault("main", "D:\\gofiles\\go-learning-notes\\go-learning\\zap日志库")
// 因为是个接口类型的values,所以还可以这样设置
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
}
官方介绍:
SetConfigType("yaml")
: 这是针对从远程获取文件的时候,用来判断文件的类型。 当本地运行时 ,这一句是不生效的。 只会执行 SetConfigName(“config”) 查找这个文件名的配置。
SetConfigFile("config.json")
,明确指定是哪个文件。展示:
// 配置文件名, 不加扩展 viper.SetConfigName("config") // name of config file (without extension) // 设置文件的扩展名 viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name // 查找配置文件所在路径 viper.AddConfigPath("/etc/appname/") // path to look for the config file in // 可以调用多次,添加多个配置文件路径 viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths // 在当前路径进行查找 viper.AddConfigPath(".") // optionally look for config in the working directory // 开始查找并读取配置文件 err := viper.ReadInConfig() // Find and read the config file if err != nil { // Handle errors reading the config file panic(fmt.Errorf("Fatal error config file: %w \n", err)) }
在当前路径下创建查找,会依次从配置的路径查找
可以按照这种写法,处理特定的找不到配置文件的情况
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found; ignore error if desired
} else {
// Config file was found but another error was produced
}
}
官方介绍场景作用:从配置文件中读取是有用的,但有时您希望存储在运行时所做的所有修改。为此,有一堆命令可用,每个命令都有自己的目的。
命令介绍
展示:
// 将当前的配置写入 'viper.AddConfigPath()' and 'viper.SetConfigName' 设置的文件
viper.WriteConfig() // writes current config to predefined path set by 'viper.AddConfigPath()' and 'viper.SetConfigName'
// 安全写,不会覆盖
viper.SafeWriteConfig()
// 写到另一个配置文件
viper.WriteConfigAs("/path/to/my/.config")
viper.SafeWriteConfigAs("/path/to/my/.config") // will error since it has already been written
viper.SafeWriteConfigAs("/path/to/my/.other_config")
viper 支持在运行时实时读取配置文件的功能。不需要重启才能生效配置文件了!
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})
viper.WatchConfig()
实际例子展示:前面的 viper的设置,就是前文的一些设置
r := gin.Default()
r.GET("/version", func(c *gin.Context){
c.JSON(http.StatusOK, gin.H{
"name": "haungdonglin",
"age": 18,
// 读取配置里的 version
"version": viper.Get("version").(string),
})
})
// 获取配置文件中的端口号
r.Run(":" + viper.Get("port").(string))
设置的配置文件:
运行程序,成功启动 8080端口。输入:http://127.0.0.1:8080/version,得到结果:
还下面不停止服务器: 继续修改配置文件, 会提示我们修改的信息,回调函数。并且再次访问,会得到新的version值。
官方介绍:除了这些提供给你的之外: such as files, environment variables, flags, and remote K/V store。 你还可以自定定义 所需要得配制源,然后提供给 viper。
viper.SetConfigType("yaml") // or viper.SetConfigType("YAML") // any approach to require this configuration into your program. // 将配置转换为 字节类型的slice,再读取 var yamlExample = []byte(` Hacker: true name: steve hobbies: - skateboarding - snowboarding - go clothing: jacket: leather trousers: denim age: 35 eyes : brown beard: true `) viper.ReadConfig(bytes.NewBuffer(yamlExample)) viper.Get("name") // this would be "steve"
viper.Set("Verbose", true)
viper.Set("LogFile", LogFile)
别名允许单个值被多个键引用。
// 这里建立别名
viper.RegisterAlias("loud", "Verbose")
// 使用这俩名字的效果是相同的
viper.Set("verbose", true) // same result as next line
viper.Set("loud", true) // same result as prior line
viper.GetBool("loud") // true
viper.GetBool("verbose") // true
可以直接查看文档介绍: https://github.com/spf13/viper#working-with-environment-variables
实例
// 自动转换为大写
SetEnvPrefix("spf") // will be uppercased automatically
// 绑定键名
BindEnv("id")
// 默认的就为这个SPF_ID
os.Setenv("SPF_ID", "13") // typically done outside of the app
id := Get("id") // 13
没咋用过,可以看官方文档
package main import ( "flag" "github.com/spf13/pflag" ) func main() { // using standard library "flag" package flag.Int("flagname", 1234, "help message for flagname") pflag.CommandLine.AddGoFlagSet(flag.CommandLine) pflag.Parse() viper.BindPFlags(pflag.CommandLine) i := viper.GetInt("flagname") // retrieve value from viper // ... }
还要远程读取等内容,就不介绍了,没使用过。文档都要介绍和 例子。
下面例子展示的: json文件形式的嵌套配置文件。
{ "host": { "address": "localhost", "port": 5799 }, "datastore": { "metric": { "host": "127.0.0.1", "port": 3099 }, "warehouse": { "host": "198.0.0.1", "port": 2112 } } }
使用 点 . 分隔符,进行嵌套访问:GetString("datastore.metric.host") // (returns "127.0.0.1")
还有下面的情况:
{ "datastore.metric.host": "0.0.0.0", "host": { "address": "localhost", "port": 5799 }, "datastore": { "metric": { "host": "127.0.0.1", "port": 3099 }, "warehouse": { "host": "198.0.0.1", "port": 2112 } } } GetString("datastore.metric.host") // returns "0.0.0.0" 优先 找 名字匹配的。 再找嵌套的。
cache:
cache1:
max-items: 100
item-size: 64
cache2:
max-items: 200
item-size: 80
cache1Config := viper.Sub("cache.cache1")
// cache1Config 就代表 cache1
并且还可以定义一个缓存函数,基于 这个,便于进行缓存。
cache1 := NewCache(cache1Config)
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)
}
当解析的key 含有默认的分隔符 . 的时候,需要修改分隔符
// 修改默认的分隔符 v := viper.NewWithOptions(viper.KeyDelimiter("::")) v.SetDefault("chart::values", map[string]interface{}{ "ingress": map[string]interface{}{ "annotations": map[string]interface{}{ "traefik.frontend.rule.type": "PathPrefix", "traefik.ingress.kubernetes.io/ssl-redirect": "true", }, }, }) type config struct { Chart struct{ Values map[string]interface{} } } var C config v.Unmarshal(&C)
还支持写入嵌套的结构体,要注意 viper 的tag
type MysqlConfig struct { Host string `mapstructure:"port"` DbName string `mapstructure:"dbname"` Port int `mapstructure:"port"` } type Config struct { Port int `mapstructure:"port"` Version string `mapstructure:"version"` MysqlConfig `mapstructure:"mysql"` } var c Config _ = viper.Unmarshal(&c) fmt.Printf("c: %#v\n", c) 结果:c: main.Config{Port:8080, Version:"1.17.10", MysqlConfig:main.MysqlConfig{Host:"13306" , DbName:"sql_demo", Port:13306}}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。