"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > 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 ?

Publié le 2024-11-08
Parcourir:235

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

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

Démarshaling dynamique avec YAML v2

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

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:"-"
}
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)
}

Démarshaling dynamique avec YAML v3

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

type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-"
}
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)
}

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.

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3