Bagaimanakah anda menghuraikan medan YAML secara dinamik ke dalam struct tertentu dalam Go tanpa menggunakan peta perantaraan?

Linda Hamilton
Lepaskan: 2024-10-31 01:47:01
asal
628 orang telah melayarinya

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

Menghuraikan Medan YAML secara Dinamik kepada Struktur Khusus dalam Go

Menentukan pendekatan optimum untuk menghuraikan medan YAML secara dinamik ke dalam struct yang dipratentukan boleh menjadi cabaran biasa dalam Go. Mari kita periksa senario yang disediakan dan terokai pilihan terbaik yang tersedia.

Cabaran

Memandangkan fail YAML dengan kandungan yang berbeza-beza dan satu set struct yang mewakili jenis data yang berbeza, matlamatnya adalah untuk menghuraikan medan ini secara dinamik ke dalam struktur yang sesuai. Pendekatan yang disediakan melibatkan penggunaan peta perantaraan, tetapi penyelesaian yang lebih elegan dicari.

Penyelesaian

Menggunakan parser Yaml v2.1.0 YAML, berikut ialah pendekatan yang dipertingkatkan:

<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>
Salin selepas log masuk
<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>
Salin selepas log masuk

Penyelesaian ini secara elegan mengendalikan penghuraian dinamik dengan membenamkan jenis struct dan medan spec dalam jenis T. Jenis yamlNode memudahkan pembongkaran antara muka Spec, membolehkan pemilihan struktur konkrit yang sesuai.

Pendekatan Kemas Kini untuk YAML v3

Untuk YAML v3, pendekatan serupa boleh digunakan, dengan pelarasan kecil:

<code class="go">type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-"`
}</code>
Salin selepas log masuk
<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>
Salin selepas log masuk

Pendekatan yang dikemas kini ini menyediakan kaedah yang lebih langsung dan cekap untuk menghuraikan medan YAML secara dinamik ke dalam jenis struct yang dikehendaki tanpa memerlukan peta perantaraan atau langkah tambahan.

Atas ialah kandungan terperinci Bagaimanakah anda menghuraikan medan YAML secara dinamik ke dalam struct tertentu dalam Go tanpa menggunakan peta perantaraan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!