Maison >développement back-end >Golang >Comment analyser dynamiquement les champs YAML dans un ensemble fini de structures en Go ?

Comment analyser dynamiquement les champs YAML dans un ensemble fini de structures en Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-29 09:49:02958parcourir

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

Analyse dynamique des champs YAML en un ensemble fini de structures dans Go

L'analyse des fichiers YAML est une tâche courante dans de nombreuses applications. Cependant, un fichier YAML peut parfois contenir des champs qui doivent être représentés par différents types de structures. Cela peut conduire à un code complexe et à des fichiers YAML encombrés.

Par exemple, considérons les fichiers YAML suivants :

<code class="yaml">kind: "foo"
spec:
  fooVal: 4</code>
<code class="yaml">kind: "bar"
spec:
  barVal: 5</code>

Et les structures correspondantes pour l'analyse :

<code class="go">type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"spec"`
}

type Foo struct {
    FooVal int `yaml:"fooVal"`
}

type Bar struct {
    BarVal int `yaml:"barVal"`
}</code>

Une approche consiste à utiliser une map[string]interface{} comme type pour le champ Spec. Cependant, cette approche peut entraîner une complexité et une consommation de mémoire supplémentaires, en particulier pour les gros fichiers YAML.

Une solution plus élégante consiste à utiliser la structure yamlNode :

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

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

Et modifier la structure Spec pour l'utiliser :

<code class="go">type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-" json:"-"`
}</code>

Avec ces modifications, la fonction UnmarshalYAML pour Spec peut analyser et désorganiser dynamiquement le champ Spec dans un type de structure spécifique :

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

Cette approche fournit une approche plus solution élégante et efficace pour analyser dynamiquement les champs YAML dans un ensemble fini de structures, rendant votre code et vos fichiers YAML beaucoup plus propres et plus faciles à gérer.

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