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

Golang解析YAML列表出错:结构体映射导致空列表问题排查

问题描述

我尝试解析如下YAML数据:

a:
  - opt:
    f1: "lol"
  - opt:
    f1: "lul"

使用如下Golang结构体进行映射:

package main

import (
    "fmt"
    "log"

    "gopkg.in/yaml.v2"
)

var data = `
a:
  - opt:
    f1: "lol"
  - opt:
    f1: "lul"
`

type T struct {
    As []A `yaml:"a"`
}

type A struct {
    Opts []Opt `yaml:"opt"`
}

type Opt struct {
    F1 string `yaml:"f1"`
}

func main() {
    t := T{}

    err := yaml.Unmarshal([]byte(data), &t)
    if err != nil {
        log.Fatalf("error: %v", err)
    }

    fmt.Printf("--- t:\n%v\n\n", t)
}

但执行后仅得到空列表:

--- t:
{[{[]} {[]}]}

请问这段代码存在什么问题?


问题原因与修正

代码的核心问题是结构体定义和YAML结构不匹配:
YAML中每个-节点下的opt是单个对象,而你在A结构体里把Opts定义成了切片类型([]Opt),yaml.v2无法将单个对象映射到切片,因此Opts始终是空切片。

修正后的代码

把A结构体中的切片字段改成单个对象类型:

package main

import (
    "fmt"
    "log"

    "gopkg.in/yaml.v2"
)

var data = `
a:
  - opt:
    f1: "lol"
  - opt:
    f1: "lul"
`

type T struct {
    As []A `yaml:"a"`
}

type A struct {
    Opt Opt `yaml:"opt"` // 将[]Opt改为Opt,匹配YAML中的单个对象
}

type Opt struct {
    F1 string `yaml:"f1"`
}

func main() {
    t := T{}

    err := yaml.Unmarshal([]byte(data), &t)
    if err != nil {
        log.Fatalf("error: %v", err)
    }

    fmt.Printf("--- t:\n%+v\n\n", t)
}

执行后会得到正确结果:

--- t:
{As:[{Opt:{F1:lol}} {Opt:{F1:lul}}]}

补充说明

如果你的YAML原本设计的是opt为数组(比如格式为opt: [{f1: "lol"}, {f1: "lul"}]),那原结构体定义才是正确的,但当前YAML结构中opt是单个对象,必须对应单个结构体字段类型。

内容的提问来源于stack exchange,提问作者k1r1t0

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:35:22