특정 필드가 미리 정의된 구조체 집합의 값으로 표현될 수 있는 YAML 파일의 경우 적합한 접근 방식은 YAML 패키지의 UnmarshalYAML 메서드를 활용하는 것입니다. 이를 통해 특정 유형에 대한 사용자 정의 역마샬링 논리를 생성할 수 있습니다.
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!