Maison  >  Article  >  développement back-end  >  Comment analyser dynamiquement un champ YAML en un ensemble fini de structures en Go ?

Comment analyser dynamiquement un champ YAML en un ensemble fini de structures en Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-10-30 23:11:30209parcourir

How to Dynamically Parse a YAML Field into a Finite Set of Structs in Go?

Analyser dynamiquement le champ YAML en un ensemble fini de structures dans Go

Introduction

L'analyse de YAML dans une structure dans Go peut être simple. Cependant, lorsqu’un champ YAML peut représenter plusieurs structures possibles, la tâche devient plus complexe. Cet article explore une approche dynamique utilisant le package YAML de Go.

Unmarshaling dynamique avec YAML v2

Pour Yaml v2, l'approche suivante peut être utilisée :

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

Démarshaling dynamique avec YAML v3

Pour Yaml v3, l'approche est légèrement différente :

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

Conclusion

Ces techniques de démarshaling dynamique permettent une analyse flexible des Champs YAML dans un ensemble fini de structures, offrant une solution plus élégante et plus efficace que la solution de contournement proposée. N'hésitez pas à explorer les extraits de code fournis et à optimiser l'approche en fonction de vos besoins spécifiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn