Heim  >  Artikel  >  Backend-Entwicklung  >  Wie können Sie YAML-Felder in Go dynamisch in bestimmte Strukturen analysieren, ohne eine Zwischenkarte zu verwenden?

Wie können Sie YAML-Felder in Go dynamisch in bestimmte Strukturen analysieren, ohne eine Zwischenkarte zu verwenden?

Linda Hamilton
Linda HamiltonOriginal
2024-10-31 01:47:01623Durchsuche

How do you dynamically parse YAML fields into specific structs in Go without using an intermediate map?

YAML-Felder dynamisch in bestimmte Strukturen in Go analysieren

Die Bestimmung des optimalen Ansatzes zum dynamischen Parsen von YAML-Feldern in vordefinierte Strukturen kann in Go eine häufige Herausforderung sein. Lassen Sie uns das bereitgestellte Szenario untersuchen und die besten verfügbaren Optionen erkunden.

Die Herausforderung

Angesichts von YAML-Dateien mit unterschiedlichem Inhalt und einer Reihe von Strukturen, die unterschiedliche Datentypen darstellen, besteht das Ziel darin, diese Felder dynamisch zu analysieren in die entsprechenden Strukturen. Der bereitgestellte Ansatz beinhaltet die Verwendung einer Zwischenkarte, es wird jedoch nach einer eleganteren Lösung gesucht.

Lösung

Unter Verwendung des Yaml-Parsers YAML v2.1.0 ist hier ein verbesserter Ansatz:

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

Diese Lösung handhabt das dynamische Parsen elegant, indem sie das Feld „Kind“ und „Spezifikation“ der Struktur in den T-Typ einbettet. Der yamlNode-Typ erleichtert das Unmarshaling der Spec-Schnittstelle und ermöglicht die Auswahl der geeigneten konkreten Struktur.

Aktualisierte Ansätze für YAML v3

Für YAML v3 kann ein ähnlicher Ansatz verwendet werden, mit Kleinere Anpassungen:

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

Diese aktualisierten Ansätze bieten eine direktere und effizientere Methode zum dynamischen Parsen von YAML-Feldern in die gewünschten Strukturtypen, ohne dass Zwischenkarten oder zusätzliche Schritte erforderlich sind.

Das obige ist der detaillierte Inhalt vonWie können Sie YAML-Felder in Go dynamisch in bestimmte Strukturen analysieren, ohne eine Zwischenkarte zu verwenden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn