首页  >  文章  >  后端开发  >  如何在 Go 中将 YAML 字段动态解析为特定结构?

如何在 Go 中将 YAML 字段动态解析为特定结构?

Susan Sarandon
Susan Sarandon原创
2024-10-31 03:50:01668浏览

How Can I Dynamically Parse a YAML Field to Specific Structs in Go?

将 YAML 字段动态解析为 Go 中的预定义结构

对于 YAML 文件,其中特定字段可以由预定结构集中的任何值表示,合适的方法是利用 YAML 包的 UnmarshalYAML 方法。这允许为特定类型创建自定义解组逻辑。

YAML v2

使用 YAML v2,以下代码实现所需的行为:

<code class="go">type yamlNode struct {
    unmarshal func(interface{}) error
}

func (n *yamlNode) UnmarshalYAML(unmarshal func(interface{}) error) error {
    n.unmarshal = unmarshal
    return nil
}

type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-"`
}</code>
<code class="go">func (s *Spec) UnmarshalYAML(unmarshal func(interface{}) error) error {
    type S Spec
    type T struct {
        S    `yaml:",inline"`
        Spec yamlNode `yaml:"spec"`
    }

    obj := &T{}
    if err := unmarshal(obj); err != nil {
        return err
    }
    *s = Spec(obj.S)

    switch s.Kind {
    case "foo":
        s.Spec = new(Foo)
    case "bar":
        s.Spec = new(Bar)
    default:
        panic("kind unknown")
    }
    return obj.Spec.unmarshal(s.Spec)
}</code>

YAML v3

对于 YAML v3,请使用以下代码:

<code class="go">type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-"`
}</code>
<code class="go">func (s *Spec) UnmarshalYAML(n *yaml.Node) error {
    type S Spec
    type T struct {
        *S   `yaml:",inline"`
        Spec yaml.Node `yaml:"spec"`
    }

    obj := &T{S: (*S)(s)}
    if err := n.Decode(obj); err != nil {
        return err
    }

    switch s.Kind {
    case "foo":
        s.Spec = new(Foo)
    case "bar":
        s.Spec = new(Bar)
    default:
        panic("kind unknown")
    }
    return obj.Spec.Decode(s.Spec)
}</code>

此方法提供了一种简单而优雅的方法来将 YAML 数据解组到一组预定义的结构中,同时避免额外的解析步骤或过多的内存消耗。

以上是如何在 Go 中将 YAML 字段动态解析为特定结构?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn