You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:03:28