使用goccy/go-yaml按Path解析YAML为结构体映射报错
问题原因
你遇到的“序列被用作映射”错误,本质是goccy/go-yaml的默认解码逻辑和你的类型定义不匹配:
- 当你用
map[string]sliceObject时,库默认认为每个键对应的值是映射结构(和sliceObject结构体的字段一一对应) - 但你的YAML里,每个键对应的值是序列(数组),两者结构冲突,所以报错
- 而
map[string][]slice是“映射对应数组”的结构,和YAML完全匹配,所以能正常解码
解决方案:自定义结构体的解码逻辑
不需要修改YAML层级,只要给sliceObject实现yaml.Unmarshaler接口,告诉库如何把YAML序列转换成你的结构体即可。
示例代码
假设你的YAML结构是这样的:
key1: - name: foo value: bar - name: baz value: qux key2: - name: abc value: def
对应的Go代码:
package main import ( "fmt" "github.com/goccy/go-yaml" ) // 定义数组元素的结构体 type Item struct { Name string `yaml:"name"` Value string `yaml:"value"` } // 你的sliceObject结构体,这里把序列内容存在Items字段中 type sliceObject struct { Items []Item } // 实现yaml.Unmarshaler接口,自定义解码逻辑 func (s *sliceObject) UnmarshalYAML(data []byte) error { // 直接将YAML序列解码到sliceObject的Items字段 return yaml.Unmarshal(data, &s.Items) } func main() { yamlContent := ` key1: - name: foo value: bar - name: baz value: qux key2: - name: abc value: def ` var result map[string]sliceObject err := yaml.Unmarshal([]byte(yamlContent), &result) if err != nil { panic(err) } fmt.Printf("%+v\n", result) }
原理说明
通过实现UnmarshalYAML接口,你覆盖了库的默认解码行为:原本库会尝试把YAML序列解析成sliceObject的结构体字段映射,现在你明确告诉它——把这个序列直接解析成sliceObject.Items数组,这样就和YAML的结构匹配了,自然不会再报错。
内容的提问来源于stack exchange,提问作者vk-code
相关产品推荐
相关产品推荐

