ホームページ > バックエンド開発 > Golang > 中間マップを使用せずに、Go で YAML フィールドを特定の構造体に動的に解析するにはどうすればよいでしょうか?

中間マップを使用せずに、Go で YAML フィールドを特定の構造体に動的に解析するにはどうすればよいでしょうか?

Linda Hamilton
リリース: 2024-10-31 01:47:01
オリジナル
711 人が閲覧しました

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

Go で YAML フィールドを特定の構造体に動的に解析する

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>
ログイン後にコピー

このソリューションは、構造体の kind フィールドと spec フィールドを T 型に埋め込むことで動的解析をエレガントに処理します。 yamlNode 型により、Spec インターフェイスのアンマーシャリングが容易になり、適切な具体的な構造体の選択が可能になります。

YAML v3 の更新されたアプローチ

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 フィールドを目的の構造体型に動的に解析するための、より直接的かつ効率的な方法を提供します。

以上が中間マップを使用せずに、Go で YAML フィールドを特定の構造体に動的に解析するにはどうすればよいでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート