聊聊Golang中很好用的viper配置模块

前言

viper 支持Yaml、Json、 TOML、HCL 等格式,读取非常的方便。

安装

go get github.com/spf13/viper

如果提示找不到golang.org/x/text/这个库,是因为golang.org/x/text/这个库在GitHub上托管的路径不一致。

解决办法:

可以从https://github.com/golang/text下载源码下来,然后到$GOPATH/src下面创建golang.org/x/文件夹(已存在的忽略),把压缩包的文件解压到golang.org/x/文件夹之下。

然后执行 go install -x golang.org/x/text 即可解决:

正文

初始结构目录如下:

准备测试使用的yaml文件,注意yaml的格式十分严格,主要是每个冒号后面必须要有空格,数组前要加“-”号表示连续(注意减号后面也有空格),内容如下:

TimeStamp: "2018-10-18 10:09:23"
Address: "Shenzhen"
Postcode: 518000
CompanyInfomation:
 Name: "Sunny"
 MarketCapitalization: 50000000
 EmployeeNum: 200
 Department:
 - "Finance"
 - "Design"
 - "Program"
 - "Sales"
 IsOpen: false

读取yaml文件:

package main
import (
 "github.com/spf13/viper"
 "fmt"
)

func main() {
 //读取yaml文件
 v := viper.New()
 //设置读取的配置文件
 v.SetConfigName("linux_config")
 //添加读取的配置文件路径
 v.AddConfigPath("./config/")
 //windows环境下为%GOPATH,linux环境下为$GOPATH
 v.AddConfigPath("$GOPATH/src/")
 //设置配置文件类型
 v.SetConfigType("yaml")

 if err := v.ReadInConfig();err != nil {
 fmt.Printf("err:%s\n",err)
 }

 fmt.Printf(
 `
 TimeStamp:%s
 CompanyInfomation.Name:%s
 CompanyInfomation.Department:%s `,
 v.Get("TimeStamp"),
 v.Get("CompanyInfomation.Name"),
 v.Get("CompanyInfomation.Department"),
 )
 /*
 result:
 TimeStamp:2018-10-18 10:09:23
 CompanyInfomation.Name:Sunny
 CompanyInfomation.Department:[Finance Design Program Sales]
 */
}

也可以直接反序列化为Struct,非常的方便:

package main
import (
 "github.com/spf13/viper"
 "fmt"
)

func main() {
 //读取yaml文件
 v := viper.New()
 //设置读取的配置文件
 v.SetConfigName("linux_config")
 //添加读取的配置文件路径
 v.AddConfigPath("./config/")
 //windows环境下为%GOPATH,linux环境下为$GOPATH
 v.AddConfigPath("$GOPATH/src/")
 //设置配置文件类型
 v.SetConfigType("yaml")
 if err := v.ReadInConfig();err != nil {
 fmt.Printf("err:%s\n",err)
 }

 fmt.Printf( `
 TimeStamp:%s
 CompanyInfomation.Name:%s
 CompanyInfomation.Department:%s `,
 v.Get("TimeStamp"),
 v.Get("CompanyInfomation.Name"),
 v.Get("CompanyInfomation.Department"),
 )
 /*
 result:
 TimeStamp:2018-10-18 10:09:23
 CompanyInfomation.Name:Sunny
 CompanyInfomation.Department:[Finance Design Program Sales]
 */
 //反序列化
 parseYaml(v)
}

type CompanyInfomation struct{
 Name string
 MarketCapitalization int64
 EmployeeNum int64
 Department []interface{}
 IsOpen bool
}

type YamlSetting struct{
 TimeStamp string
 Address string
 Postcode int64
 CompanyInfomation CompanyInfomation
} 

func parseYaml(v *viper.Viper){
 var yamlObj YamlSetting;
 if err := v.Unmarshal(&yamlObj) ; err != nil{
 fmt.Printf("err:%s",err)
 }
 fmt.Println(yamlObj)
 /*
 result:
 {2018-10-18 10:09:23 Shenzhen 518000 {Sunny 50000000 200 [Finance Design Program Sales] false}}
 */
}

viper也提供了读取Command Line参数的功能:

package main
import (
 "github.com/spf13/pflag"
 "github.com/spf13/viper"
 "fmt"
)

func main() {
 pflag.String("hostAddress", "127.0.0.1", "Server running address")
 pflag.Int64("port", 8080, "Server running port")
 pflag.Parse()

 viper.BindPFlags(pflag.CommandLine)
 fmt.Printf("hostAddress :%s , port:%s", viper.GetString("hostAddress"), viper.GetString("port"))
 /*
 example:
 go run main2.go --hostAddress=192.192.1.10 --port=9000
 help:
 Usage of /tmp/go-build183981952/b001/exe/main:
  --hostAddress string Server running address (default "127.0.0.1")
  --port int    Server running port (default 8080)
 */
 }

很多时候,我们服务器启动之后,如果临时想修改某些配置参数,需要重启服务器才能生效,但是viper提供了监听函数,可以免重启修改配置参数,非常的实用:

package main
import (
 "github.com/spf13/viper"
 "fmt"
 "golang.org/x/net/context"
 "github.com/fsnotify/fsnotify"
)

func main() {
 //读取yaml文件
 v := viper.New()
 //设置读取的配置文件
 v.SetConfigName("linux_config")
 //添加读取的配置文件路径
 v.AddConfigPath("./config/")
 //windows环境下为%GOPATH,linux环境下为$GOPATH
 v.AddConfigPath("$GOPATH/src/")
 //设置配置文件类型
 v.SetConfigType("yaml")

 if err := v.ReadInConfig(); err != nil {
 fmt.Printf("err:%s\n", err)
 }

 //创建一个信道等待关闭(模拟服务器环境)
 ctx, _ := context.WithCancel(context.Background())
 //cancel可以关闭信道
 //ctx, cancel := context.WithCancel(context.Background())
 //设置监听回调函数
 v.OnConfigChange(func(e fsnotify.Event) {
 fmt.Printf("config is change :%s \n", e.String())
 //cancel()
 })
 //开始监听
 v.WatchConfig()
 //信道不会主动关闭,可以主动调用cancel关闭
 <-ctx.Done()

 /*
 result:
 config is change :"/home/share/go/Viper/config/linux_config.yaml": CREATE
 config is change :"/home/share/go/Viper/config/linux_config.yaml": CREATE
 */
}

完结

viper还有许多好用的功能,此文章只是举例说明了很小的部分。

补充:viper-配置信息处理框架(golang)

项目地址https://github.com/spf13/viper

1. viper

viper读取配置信息的优先级顺序,从高到底:

显式调用Set函数

命令行参数

环境变量

配置文件

key/value存储系统

默认值

2. 设置值

(1)设置默认值

viper.SetDefault("ContentDir", "content")

...

(2)读取配置文件

viper.SetConfigName("xxx")  // 设置配置文件名,不要带后缀
viper.AddConfigPath("/path")  // 第一个搜索路径
viper.AddConfigPath("../etc")  // 设置为相对路径
err := viper.ReadInConfig()  // 搜索路径,并读取配置数据

(3)***监视配置文件

viper支持应用程序运行时拥有读取配置文件的能力

viper实例通过WatchConfig函数:

viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event)) {
  fmt.Println("Config file changed:", e.Name)
})

(4)Set调用

viper.Set("Verbose", true)

viper.Set("LogFile", LogFile)

(5)绑定命令行参数

***viper支持绑定pflags参数【pflags是一个命令行参数解析库】

serveCmd.Flags().Int("port", 1138, "Port to run Application server on")

viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))

3. 获取值

Get(key string) : interface{}
GetBool(key string) : bool
GetFloat64(key string) : float64
GetInt(key string) : int
GetString(key string) : string
GetStringMap(key string) : map[string]interface{}
GetStringMapString(key string) : map[string]string
GetStringSlice(key string) : []string
GetTime(key string) : time.Time
GetDuration(key string) : time.Duration
IsSet(key string) : bool

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • golang常用库之配置文件解析库-viper使用详解

    golang常用库:gorilla/mux-http路由库使用 golang常用库:配置文件解析库-viper使用 golang常用库:操作数据库的orm框架-gorm基本使用 golang常用库:字段参数验证库-validator使用 一.viper简介 viper 配置管理解析库,是由大神 Steve Francia 开发,他在google领导着 golang 的产品开发,他也是 gohugo.io 的创始人之一,命令行解析库 cobra 开发者.总之,他在golang领域是专家,很牛的一个

  • golang 使用 viper 读取自定义配置文件

    viper 支持 Yaml.Json. TOML.HCL 等格式,读取非常的方便. viper 官网有案例:https://github.com/spf13/viper go get github.com/spf13/viper 创建 config.yaml 文件 database: driver: mysql host: 127.0.0.1 port: 3306 username: blog dbname: blog password: 123456 建一个 config.go 用于初始化配置

  • 使用dep 配置golang 开发环境的操作方法

    概要 golang 的包管理一直没有官方统一的解决方案,因此也产生了很多非官方的包管理工具. 之前我一直使用的 gb(https://getgb.io/) 能够很好的隔开各个 golang 工程,当时 gb 创建的工程不太融入已有的 GOPATH 中. gb 相当于是把工程的目录作为 GOPATH,并且它的 vendor 目录也和 golang 自己的 vendor 不太一样. dep 的 Roadmap 中已经制定了成为 golang 官方包管理工具的计划, 所以,使用 dep 来组织自己的

  • 聊聊Golang中很好用的viper配置模块

    前言 viper 支持Yaml.Json. TOML.HCL 等格式,读取非常的方便. 安装 go get github.com/spf13/viper 如果提示找不到golang.org/x/text/这个库,是因为golang.org/x/text/这个库在GitHub上托管的路径不一致. 解决办法: 可以从https://github.com/golang/text下载源码下来,然后到$GOPATH/src下面创建golang.org/x/文件夹(已存在的忽略),把压缩包的文件解压到gol

  • 聊聊golang中多个defer的执行顺序

    golang 中多个 defer 的执行顺序 引用 Ture Go 中的一个示例: package main import "fmt" func main() { fmt.Println("counting") for i := 0; i < 10; i++ { defer fmt.Println(i) } fmt.Println("done") } 程序执行结果为: counting done 9 8 7 6 5 4 3 2 1 0 从结

  • 简单聊聊Golang中defer预计算参数

    目录 什么是defer Go语言defer预计算参数 总结 什么是defer defer用来声明一个延迟函数,把这个函数放入到一个栈上, 当外部的包含方法return之前,返回参数到调用方法之前调用,也可以说是运行到最外层方法体的"}"时调用.我们经常用他来做一些资源的释放,比如关闭io操作 func doSomething(fileName string) { file,err := os.Open(fileName) if err != nil { panic(err) } def

  • 在 Golang 中使用 Cobra 创建 CLI 应用

    虽然现在我们使用的大多数软件都是可视化的,很容易上手,但是这并不代表 CLI(命令行)应用就没有用武之地了,特别是对于开发人员来说,还是会经常和 CLI 应用打交道.而 Golang 就非常适合用来构建 CLI 应用,下面我们就将来介绍如何在 Golang 中构建一个 CLI 应用. 对于开发人员来说平时可能就需要使用到很多 CLI 工具,比如 npm.node.go.python.docker.kubectl 等等,因为这些工具非常小巧.没有依赖性.非常适合系统管理或者一些自动化任务等等. 我

  • golang中包无法引入问题解决

    目录 前言 问题背景 问题现象 问题解决 1.强制开启GO111MODULE 2.切换代理 问题总结 前言 刚接触golang不久,有些环境无法融会贯通,现在针对开发过程中遇到的问题做个排查记录 问题背景 开发环境区分不同网段,同一个程序引入到另一个环境后,对应的包无法下载 问题现象 程序导入另一个环境后,初始化操作就是下载包:执行go mod tidy后,出现下面错误 go: github.com/Sirupsen/logrus@v1.0.1: Get " https://proxy.gola

  • Golang中如何使用lua进行扩展详解

    前言 最近在项目中需要使用lua进行扩展,发现github上有一个用golang编写的lua虚拟机,名字叫做gopher-lua.使用后发现还不错,借此分享给大家,下面话不多说了,来一起看看详细的介绍吧. 数据类型 lua中的数据类型与golang中的数据类型对应关系作者已经在文档中说明,值得注意的是类型是以L开头的,类型的名称是以LT开头的. golang中的数据转换为lua中的数据就必须转换为L开头的类型: str := "hello" num := 10 L.LString(st

  • Golang中数据结构Queue的实现方法详解

    前言 本文主要给大家介绍了关于Golang中数据结构Queue实现的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 需求 队列的特性较为单一,基本操作即初始化.获取大小.添加元素.移除元素等.最重要的特性就是满足先进先出. 实现 接下来还是按照以前的套路,一步一步来分析如何利用Go的语法特性实现Queue这种数据结构. 定义 首先定义每个节点Node结构体,照例Value的值类型可以是任意类型,节点的前后指针域指针类型为node type node struct {

  • golang中make和new的区别示例详解

    前言 本文主要给大家介绍了关于golang中make和new区别的相关内容,分享出来供大家参考学习,话不多说了,来一起看看详细的介绍: new 和 make 都可以用来分配空间,初始化类型,但是它们确有不同. new(T) 返回的是 T 的指针 new(T) 为一个 T 类型新值分配空间并将此空间初始化为 T 的零值,返回的是新值的地址,也就是 T 类型的指针 *T,该指针指向 T 的新分配的零值. p1 := new(int) fmt.Printf("p1 --> %#v \n &quo

  • Golang中switch语句和select语句的用法教程

    本文主要给大家介绍了关于Golang中switch和select用法的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 一.switch语句 switch语句提供了一个多分支条件执行的方法.每一个case可以携带一个表达式或一个类型说明符.前者又可被简称为case表达式.因此,Go语言的switch语句又分为表达式switch语句和类型switch语句. 1.表达式switch语句 var name string ... switch name { case "Golang"

  • GoLang 中的随机数的示例代码

    随机数我们都知道,就是计算机通过某种算法,"随机"的生成一个数字.很多编程语言都有内置的方法来生成随机数,那么 GoLang 中是怎样一种情况呢? 伪随机数 我们都知道"随机数"在现实生活中的概念,可能你随手抛一个硬币,就可以说其结果是随机的,但是在计算机中要确定一个"随机数"真的是"随机数",那可是有标准的,不是你随随便便说是就是. 根据密码学原理,要想对一个"随机数"进行随机性检验有以下几个标准: 统计

随机推荐