Heim >Backend-Entwicklung >Golang >Wie kann man YAML-Felder in Go dynamisch in einen endlichen Satz von Strukturen analysieren?

Wie kann man YAML-Felder in Go dynamisch in einen endlichen Satz von Strukturen analysieren?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-29 09:49:02977Durchsuche

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

YAML-Felder dynamisch in einen endlichen Satz von Strukturen in Go analysieren

Das Parsen von YAML-Dateien ist in vielen Anwendungen eine häufige Aufgabe. Manchmal kann eine YAML-Datei jedoch Felder enthalten, die durch verschiedene Arten von Strukturen dargestellt werden müssen. Dies kann zu komplexem Code und unübersichtlichen YAML-Dateien führen.

Betrachten Sie beispielsweise die folgenden YAML-Dateien:

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

Und die entsprechenden Strukturen zum Parsen:

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

Ein Ansatz besteht darin, ein „map[string]interface{}“ als Typ für das Spec-Feld zu verwenden. Dieser Ansatz kann jedoch insbesondere bei großen YAML-Dateien zu zusätzlicher Komplexität und Speicherverbrauch führen.

Eine elegantere Lösung besteht darin, die yamlNode-Struktur zu verwenden:

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

Und die Spec-Struktur zu ändern um es zu verwenden:

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

Mit diesen Änderungen kann die UnmarshalYAML-Funktion für Spec das Spec-Feld dynamisch analysieren und in einen bestimmten Strukturtyp entmarshalieren:

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

Dieser Ansatz bietet mehr elegante und effiziente Lösung zum dynamischen Parsen von YAML-Feldern in einen endlichen Satz von Strukturen, wodurch Ihr Code und Ihre YAML-Dateien viel sauberer und einfacher zu verwalten werden.

Das obige ist der detaillierte Inhalt vonWie kann man YAML-Felder in Go dynamisch in einen endlichen Satz von Strukturen analysieren?. 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