Menghuraikan Medan YAML secara dinamik kepada Struktur Khusus dalam Go
Fail YAML selalunya mengandungi medan yang boleh diwakili oleh berbilang jenis struct. Untuk memudahkan kod dan fail YAML, pertimbangkan contoh YAML berikut:
kind: "foo" spec: fooVal: 4
kind: "bar" spec: barVal: 5
Struktur yang sepadan untuk menghurai ialah:
<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>
Semasa menggunakan peta[rentetan]antara muka{ } untuk medan Spec ialah pilihan, ia boleh menjadi kompleks untuk fail YAML yang lebih besar.
Penyelesaian Elegan Menggunakan Custom Unmarshaler
Pendekatan alternatif melibatkan mencipta Unmarshaler tersuai untuk jenis Spec. Untuk digunakan dengan yaml.v2, laksanakan perkara berikut:
<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>
Untuk yaml.v3, gunakan yang berikut:
<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>
Penyelesaian ini memetakan YAML secara dinamik medan ke struct yang sesuai berdasarkan medan "jenis", mengalih keluar keperluan untuk langkah tambahan atau penggunaan memori.
Atas ialah kandungan terperinci Bagaimana Menghuraikan Medan YAML secara Dinamik kepada Struktur Khusus dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!