Go에서 YAML을 구조체로 구문 분석하는 것은 간단할 수 있습니다. 그러나 YAML 필드가 가능한 여러 구조체를 나타낼 수 있으면 작업이 더 복잡해집니다. 이 기사에서는 Go의 YAML 패키지를 사용하는 동적 접근 방식을 살펴봅니다.
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은 유한한 구조체 세트로 필드화되어 제안된 해결 방법보다 더 우아하고 효율적인 솔루션을 제공합니다. 제공된 코드 스니펫을 자유롭게 탐색하고 특정 요구 사항에 따라 접근 방식을 최적화하세요.
위 내용은 Go에서 YAML 필드를 유한 구조체 세트로 동적으로 구문 분석하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!