在 Go 中將 YAML 解析為結構體非常簡單。但是,當 YAML 欄位可以表示多個可能的結構時,任務就會變得更加複雜。本文探討了使用 Go 的 YAML 套件的動態方法。
對於 Yaml v2,可以使用以下方法:
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:"-"
}
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)
}
對於 Yaml v3,方法略有不同:
type Spec struct {
Kind string `yaml:"kind"`
Spec interface{} `yaml:"-"
}
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)
}
這些動態解組技術允許將 YAML 欄位靈活解析為有限的結構集,從而提供比建議的解決方法更優雅、更有效率的解決方案。請隨意探索提供的程式碼片段並根據您的具體要求優化方法。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3