"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como analisar dinamicamente um campo YAML em um conjunto finito de estruturas no Go?

Como analisar dinamicamente um campo YAML em um conjunto finito de estruturas no Go?

Publicado em 2024-11-08
Navegar:610

How to Dynamically Parse a YAML Field into a Finite Set of Structs in Go?

Analisar dinamicamente o campo YAML para um conjunto finito de estruturas em Go

Introdução

Analisar YAML em uma estrutura em Go pode ser simples. No entanto, quando um campo YAML pode representar múltiplas estruturas possíveis, a tarefa se torna mais complexa. Este artigo explora uma abordagem dinâmica usando o pacote YAML do Go.

Desempacotamento dinâmico com YAML v2

Para Yaml v2, a seguinte abordagem pode ser usada:

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)
}

Desempacotamento dinâmico com YAML v3

Para Yaml v3, a abordagem é um pouco diferente:

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)
}

Conclusão

Essas técnicas de desempacotamento dinâmico permitem a análise flexível de campos YAML em um conjunto finito de estruturas, fornecendo uma solução mais elegante e eficiente do que a solução alternativa proposta. Sinta-se à vontade para explorar os trechos de código fornecidos e otimizar a abordagem com base em seus requisitos específicos.

Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3