確定將YAML 欄位動態解析為預定義結構的最佳方法可能是Go 中的常見挑戰。讓我們檢查提供的場景並探索可用的最佳選項。
給定具有不同內容的 YAML 檔案和一組表示不同資料類型的結構,目標是動態解析這些欄位到適當的結構中。提供的方法涉及使用中間映射,但尋求更優雅的解決方案。
利用YAML v2.1.0 Yaml 解析器,這是一種改進的方法:
<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>
該解決方案透過在T 類型中嵌入結構體的kind 和spec 欄位來優雅地處理動態解析。 yamlNode 類型有助於解組 Spec 接口,從而允許選擇適當的特定結構。
對於YAML v3,可以使用類似的方法,細微調整:
<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>
這些更新的方法提供了一種更直接、更有效率的方法,可以將YAML 欄位動態解析為所需的結構類型,而不需要中間映射或其他步驟。
以上是如何在不使用中間映射的情況下將 YAML 欄位動態解析為 Go 中的特定結構?的詳細內容。更多資訊請關注PHP中文網其他相關文章!