Maison >développement back-end >Golang >Comment puis-je analyser dynamiquement un champ YAML en structures spécifiques dans Go ?

Comment puis-je analyser dynamiquement un champ YAML en structures spécifiques dans Go ?

Susan Sarandon
Susan Sarandonoriginal
2024-10-31 03:50:01793parcourir

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

Analyser dynamiquement le champ YAML en structures prédéfinies dans Go

Pour un fichier YAML où un champ particulier peut être représenté par n'importe quelle valeur d'un ensemble prédéterminé de structures, un L'approche serait d'utiliser la méthode UnmarshalYAML du package YAML. Cela permet la création d'une logique de démarshaling personnalisée pour des types spécifiques.

YAML v2

En utilisant YAML v2, le code suivant obtient le comportement souhaité :

<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

Pour YAML v3, utilisez le code suivant :

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

Cette approche fournit un moyen simple et élégant de regrouper les données YAML dans un ensemble prédéfini de structures tout en évitant étapes d'analyse supplémentaires ou consommation excessive de mémoire.

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