本文使用 golang 库 viper 对 yaml 文件进行解析。
下载
执行 go get github.com/spf13/viper
安装。
golang 中 yaml 文件解析较多。本文选用 viper 进行解析,主要因为笔者的命令终端库使用了 viper 和 cobra,前者解析 yaml 文件,后者进行命令参数的解析,能方便形成程序主体框架。
测试
yaml 配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| # yaml测试样例 # null 或 NULL 为关键字,不能写
# 名称 # 字符串 name: conf file
# 版本 # 如按浮点,2.0会转换成2 # 如按字符串,保留原样 version: 2.0
# 布尔类,转换为1或0 need: true
# 时间 time: 2020-10-03T09:21:13
empty: nul
# 对象 # 加双引号会转义\n,即会换行 my: name: late \n lee name1: "late \n lee" age: 99 # 块 text: | hello world!
# 数组 fruit: - apple - apple1 - apple2 - apple3 - apple4 - apple5
# 多级数组 multi: sta: - 110 210 ddd 99 - 133 135 1 2 1588 1509 - 310-410 - 333-444
|
该示例基本涵盖了大部分的 yaml 格式。包括:字符串,数值、数组、多级map。
测试代码
测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| package main
import ( "fmt" true"os" true"github.com/spf13/viper" )
var ( truecfgFile string )
func main() { trueif cfgFile != "" { truetrue// Use config file from the flag. truetrueviper.SetConfigFile(cfgFile) true} else { truetrueviper.AddConfigPath("./") truetrueviper.SetConfigName("config") truetrueviper.SetConfigType("yaml") true}
trueviper.AutomaticEnv() // read in environment variables that match
trueerr := viper.ReadInConfig(); trueif err != nil { truetruefmt.Println("'config.yaml' file read error:", err) truetrueos.Exit(0) true} name := viper.GetString("name") version := viper.GetString("version")
need := viper.GetBool("need") theTime := viper.GetString("time") empty := viper.GetString("empty") text := viper.GetString("text")
fmt.Printf("need: %v name: %v=\n version: %v \ntime: %v \nempty: %s \ntext: %v\n", need, name, version, theTime, empty, text) name = viper.GetString("my.name") name1 := viper.GetString("my.name1") age := viper.GetInt("my.age") fmt.Printf("name: %v, name1: %v age: %v \n", name, name1, age)
newSta := viper.GetStringSlice("multi.sta") for idx, value := range newSta { fmt.Printf("sta[%d]: %v\n", idx, value) }
fruit := viper.GetStringSlice("fruit")
fmt.Printf("fruit: %v\n", fruit) bad := viper.GetString("bad") bad1 := viper.GetString("my.bad") fmt.Printf("bad: %v bad1: %v\n", bad, bad1) }
|
执行go build
进行编译。
输出结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $ ./yaml_test.exe need: true name: conf file= version: 2 time: 2020-10-03T09:21:13 empty: nul text: hello world!
name: late \n lee, name1: late lee age: 99 sta[0]: 110 210 ddd 99 sta[1]: 133 135 1 2 1588 1509 sta[2]: 310-410 sta[3]: 333-444 fruit: [apple apple1 apple2 apple3 apple4 apple5] bad: bad1:
|
结果说明
1、name: "late \n lee"
输出会换行。而 name: late \n lee
则会原样输出。
2、参数的值不能为 null 或 NULL,但可以为nul。如果为 null,解析的值为空。
3、如果字段不存在,不会报错,解析得到的值为空。