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

流式YAML解析中如何对当前文档进行两次解码?

流式YAML解析中如何对当前文档进行两次解码?

这个问题我之前也碰到过,核心痛点就是yaml.Decoder的Decode方法每次调用都会“消费”掉当前文档的内容,直接连续调用两次的话,第二次就会跳到下一个文档了。给你个简单靠谱的解决思路:先把当前文档完整解析成一个yaml.Node节点,之后你就可以对这个节点反复解码,想转成什么结构体都行,完全不会影响后续文档的解析~

具体修改后的代码示例如下:

package main

import (
    "errors"
    "fmt"
    "io"
    "os"

    "gopkg.in/yaml.v3"
)

type Spec struct {
    Name string `yaml:"name"`
}

type Special struct {
    Integer string `yaml:"integer"`
}

func main() {
    f := os.Stdin
    d := yaml.NewDecoder(f)
    for {
        // 第一步:把当前完整文档解析为yaml.Node,这一步仅读取当前文档,不会移动到下一个
        var node yaml.Node
        err := d.Decode(&node)
        if errors.Is(err, io.EOF) {
            break
        }
        if err != nil {
            panic(err)
        }

        // 第一次解码:从Node中解析出Spec,拿到name字段
        var spec Spec
        if err := node.Decode(&spec); err != nil {
            panic(err)
        }
        fmt.Printf("name is '%s'\n", spec.Name)

        // 根据name判断,决定用哪个结构体再次解码当前文档
        if spec.Name == "special" {
            var special Special
            if err := node.Decode(&special); err != nil {
                panic(err)
            }
            fmt.Printf("special integer value: '%s'\n", special.Integer)
        }
        // 这里可以扩展其他name对应的结构体解析逻辑
    }
}

原理其实很简单:yaml.Node就像是当前YAML文档在内存中的完整快照,把文档读进Node之后,所有的解码操作都是在内存里对这个快照进行处理,完全不会触动yaml.Decoder的文档指针。不管你对Node调用多少次Decode,都只会解析同一个文档的内容,后续循环里再调用d.Decode(&node)时,才会读取下一个文档。

另外提个小细节:如果YAML文档里有某些字段在你要解析的结构体中不存在,yaml.Node的Decode方法会自动忽略这些字段,不用额外处理(除非你开启了严格解码模式)。

备注:内容来源于stack exchange,提问作者guettli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:00:28