[Golang] yaml解析遇到内嵌结构体的问题

最近在开发中,组员报告了一个问题,读取配置文件的时候内嵌结构体(anonymous field)接收不到配置文件的参数。 经过排查,发现yaml编解码包的行为和json不太一样,这次就是这个差异导致的。

yaml对内嵌结构体的赋值策略和json不同

上代码:

 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
package main

import (
	"fmt"

	"gopkg.in/yaml.v3"
)

type SubData struct {
	Sub1 string `yaml:"sub1"`
}

type Config struct {
	SubData

	Data1 string `yaml:"data1"`
}

func main() {
    y1 := `
data1: "aaaa"
sub1: "bbbb"
`
    c := Config{}
	err := yaml.Unmarshal([]byte(y1), &c)
	if err != nil {
		panic(err)
	}

	fmt.Println(d)
}

此处的预期输出应该为:{{bbbb} aaaa},但是实际得到的确是:{{} aaaa},内嵌结构体并没有收到的数据,这和json包的行为不一样。

后来通过对yaml包的深入了解,原来yaml包需要添加:inline的tag属性,才可以达到效果。

1
2
3
4
5
6

type Config struct {
	SubData `yaml:",inline"`

	Data1 string `yaml:"data1"`
}

得到正确的结果:{{bbbb} aaaa}

另外,如果不加inline,那么yaml数据应该使用如下数据格式:

1
2
3
data1: "aaaa"
subdata: # 与结构体同名
    sub1: "bbbb"