Rumah >pembangunan bahagian belakang >Golang >Bagaimana Menghuraikan Medan YAML Secara Dinamik ke dalam Set Struktur Terhad dalam Go?

Bagaimana Menghuraikan Medan YAML Secara Dinamik ke dalam Set Struktur Terhad dalam Go?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-10-29 09:49:02914semak imbas

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

Menghuraikan Medan YAML Secara Dinamik kepada Set Struktur Terhad dalam Go

Menghuraikan fail YAML ialah tugas biasa dalam banyak aplikasi. Walau bagaimanapun, kadangkala fail YAML boleh mengandungi medan yang perlu diwakili oleh pelbagai jenis struct. Ini boleh membawa kepada kod kompleks dan fail YAML yang bersepah.

Sebagai contoh, pertimbangkan fail YAML berikut:

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

Dan struct yang sepadan untuk menghurai:

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

Satu pendekatan ialah menggunakan peta[rentetan]antara muka{} sebagai jenis untuk medan Spec. Walau bagaimanapun, pendekatan ini boleh membawa kepada kerumitan tambahan dan penggunaan memori, terutamanya untuk fail YAML yang besar.

Penyelesaian yang lebih elegan ialah menggunakan struct 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>

Dan ubah suai struct Spec untuk menggunakannya:

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

Dengan perubahan ini, fungsi UnmarshalYAML untuk Spec secara dinamik boleh menghuraikan dan menyahmarshal medan Spec ke dalam jenis struct tertentu:

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

Pendekatan ini menyediakan lebih banyak penyelesaian yang elegan dan cekap untuk menghuraikan medan YAML secara dinamik ke dalam set struktur terhingga, menjadikan kod dan fail YAML anda lebih bersih dan lebih mudah untuk diurus.

Atas ialah kandungan terperinci Bagaimana Menghuraikan Medan YAML Secara Dinamik ke dalam Set Struktur Terhad dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn