1、下载viper包
# go get github.com/spf13/viper
2、viper读取顺序
- 调用
Set
显式设置的; - 命令行选项;
- 环境变量;
- 配置文件;
- 默认值。
3、example.toml文件
appname = test
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
[servers]
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"
[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"
[clients]
data = [ ["gamma", "delta"], [1, 2] ]
4、代码示例
package main
import (
"fmt"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"log"
)
func init() {
pflag.String("appname", "appname", "")
viper.BindPFlags(pflag.CommandLine)
}
func main() {
//解析命令行
pflag.Parse()
//1.读取example.toml配置文件
viper.SetConfigName("example") //设置文件名时不要带后缀
viper.SetConfigType("toml")
viper.AddConfigPath(".") //搜索路径可以设置多个,viper 会根据设置顺序依次查找
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("read config failed: %v", err)
}
//2.获取所有值
fmt.Println("all settings: ", viper.AllSettings())
//3.获取命令行传入的值
fmt.Println("appname: ", viper.Get("appname"))
//4.设置database.server的值,那么设置的值优先级最高
viper.Set("database.server","127.0.0.1")
fmt.Println("appname: ", viper.Get("appname"))
//5.获取Bool/Float64/Int/String/Time/Duration/IntSlice/StringSlice类型
//获取 appname = test
//如果命令行传入了,获取到的appname是命令行的值而不是配置文件里的值
fmt.Println("appname",viper.GetString("appname"))
/*6.获取嵌套Bool/Float64/Int/String等
[database]
server = "192.168.1.1"
[servers]
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"
*/
fmt.Println(viper.GetString("database.server"))
fmt.Println(viper.GetString("servers.alpha.ip"))
/*7.获取Bool/Float64/Int/String等数组
[database]
ports = [ 8001, 8001, 8002 ]
*/
fmt.Println("port", viper.GetIntSlice("database.ports")[0])
/*8.获取多层数组中的值
[clients]
data = [ ["gamma", "delta"], [1, 2] ]
*/
clients := viper.GetStringMap("clients")
for _, v := range clients {
fmt.Println(v) //[[gamma delta] [1 2]]
for _, j := range v.([]interface{}) {
fmt.Println(j)
for _, k := range j.([]interface{}) {
fmt.Println(k)
}
}
}
//9.绑定单独的环境变量
viper.BindEnv("GOROOT", "GOROOT")
fmt.Println("GOROOT: ", viper.Get("GOROOT"))
//10.绑定全部环境变量,获取环境变量中的值
viper.AutomaticEnv()
fmt.Println("GOPATH: ", viper.Get("GOPATH"))
//11.设置默认值
viper.SetDefault("appversion", "0.0.1")
fmt.Println("appversion", viper.Get("appversion"))
}
5、Unmarshal解析toml
viper 支持将配置Unmarshal
到一个结构体中,为结构体中的对应字段赋值。
package main
import (
"fmt"
"github.com/spf13/viper"
"log"
)
type database struct {
Server string
Ports []int
}
type config struct {
Database database
}
func main() {
viper.SetConfigName("example")
viper.SetConfigType("toml")
viper.AddConfigPath("../")
if err := viper.ReadInConfig(); err != nil {
log.Fatal("read config failed,err:", err)
}
var c config
viper.Unmarshal(&c)
fmt.Println(c.Database.Ports[1])
}
6、viper监听配置文件变化
在Sleep的10s内修改database.server的值,Sleep结束后,会打印新的值。
func main() {
viper.SetConfigName("example")
viper.SetConfigType("toml")
viper.AddConfigPath("../")
if err := viper.ReadInConfig(); err != nil {
log.Fatal("read config failed,err:", err)
}
viper.WatchConfig()
fmt.Println("server before sleep: ", viper.Get("database.server"))
time.Sleep(time.Second * 10)
fmt.Println("server after sleep: ", viper.Get("database.server"))
}
参考链接:https://studygolang.com/articles/26215?fr=sidebar
如有不对,烦请指出,感谢~