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 では、同様のアプローチを使用できます。マイナー調整:
<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 サイトの他の関連記事を参照してください。