Wie kann ich ein YAML-Feld dynamisch in bestimmte Strukturen in Go analysieren?

Linda Hamilton
Freigeben: 2024-10-28 12:58:30
Original
316 Leute haben es durchsucht

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

Dynamisches Parsen eines YAML-Felds in bestimmte Strukturen in Go

YAML-Dateien enthalten oft Felder, die durch mehrere Arten von Strukturen dargestellt werden können. Um Code und YAML-Dateien zu vereinfachen, betrachten Sie die folgenden YAML-Beispiele:

kind: "foo"
spec:
  fooVal: 4
Nach dem Login kopieren
kind: "bar"
spec:
  barVal: 5
Nach dem Login kopieren

Die entsprechenden Strukturen zum Parsen sind:

<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>
Nach dem Login kopieren

Bei Verwendung einer Map[string]-Schnittstelle{ } für das Spec-Feld ist eine Option, es kann bei größeren YAML-Dateien komplex werden.

Elegante Lösung mit benutzerdefiniertem Unmarshaler

Ein alternativer Ansatz besteht darin, einen benutzerdefinierten Unmarshaler für zu erstellen der Spezifikationstyp. Implementieren Sie für die Verwendung mit yaml.v2 Folgendes:

<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>
Nach dem Login kopieren
<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>
Nach dem Login kopieren

Verwenden Sie für yaml.v3 Folgendes:

<code class="go">type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-"`
}</code>
Nach dem Login kopieren
<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>
Nach dem Login kopieren

Diese Lösung ordnet YAML dynamisch zu Feld basierend auf dem Feld „Art“ in die entsprechende Struktur umwandeln, sodass keine zusätzlichen Schritte oder Speicherverbrauch erforderlich sind.

Das obige ist der detaillierte Inhalt vonWie kann ich ein YAML-Feld dynamisch in bestimmte Strukturen in Go analysieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!