首頁 > 後端開發 > Golang > 主體

如何在 Go 中將 YAML 欄位動態解析為特定結構?

Linda Hamilton
發布: 2024-10-28 12:58:30
原創
316 人瀏覽過

How to Dynamically Parse a YAML Field to Specific Structs in Go?

在 Go 中將 YAML 欄位動態解析為特定結構

YAML 檔案通常包含可以由多種類型的結構表示的欄位。為了簡化程式碼和YAML 文件,請考慮以下YAML 範例:

kind: "foo"
spec:
  fooVal: 4
登入後複製
kind: "bar"
spec:
  barVal: 5
登入後複製

用於解析的對應結構為:

<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>
登入後複製

使用map[string] 介面時{ Spec 欄位的} 是一個選項,對於較大的YAML 文件,它可能會變得複雜。

使用自訂 Unmarshaler 的優雅解決方案

另一種方法涉及為以下物件建立自訂 Unmarshaler規格類型。若要與yaml.v2 一起使用,請實現以下內容:

<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>
登入後複製

對於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根據「kind」欄位將欄位新增至適當的結構,從而無需額外的步驟或記憶體消耗。

以上是如何在 Go 中將 YAML 欄位動態解析為特定結構?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!