yaml文件解析:golang篇

本文使用 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、如果字段不存在,不会报错,解析得到的值为空。