Go에서 YAML을 구조체로 구문 분석하는 것은 간단할 수 있습니다. 그러나 YAML 필드가 가능한 여러 구조체를 나타낼 수 있으면 작업이 더 복잡해집니다. 이 문서에서는 Go의 YAML 패키지를 사용하는 동적 접근 방식을 살펴봅니다.
Yaml v2의 경우 다음 접근 방식을 사용할 수 있습니다.
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:"-"
}
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)
}
Yaml v3의 경우 접근 방식이 약간 다릅니다.
type Spec struct {
Kind string `yaml:"kind"`
Spec interface{} `yaml:"-"
}
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)
}
이러한 동적 역정렬화 기술을 사용하면 YAML 필드를 유한 구조체 세트로 유연하게 구문 분석할 수 있어 제안된 해결 방법보다 더 우아하고 효율적인 솔루션을 제공할 수 있습니다. 제공된 코드 조각을 자유롭게 살펴보고 특정 요구 사항에 따라 접근 방식을 최적화하세요.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3