"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ¿Cómo analizar dinámicamente un campo YAML en un conjunto finito de estructuras en Go?

¿Cómo analizar dinámicamente un campo YAML en un conjunto finito de estructuras en Go?

Publicado el 2024-11-08
Navegar:559

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

Analizar dinámicamente el campo YAML en un conjunto finito de estructuras en Go

Introducción

Analizar YAML en una estructura en Go puede ser sencillo. Sin embargo, cuando un campo YAML puede representar múltiples estructuras posibles, la tarea se vuelve más compleja. Este artículo explora un enfoque dinámico utilizando el paquete YAML de Go.

Desclasificación dinámica con YAML v2

Para Yaml v2, se puede utilizar el siguiente enfoque:

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

Desclasificación dinámica con YAML v3

Para Yaml v3, el enfoque es ligeramente 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)
}

Conclusión

Estas técnicas de clasificación dinámica permiten un análisis flexible de campos YAML en un conjunto finito de estructuras, lo que proporciona una solución más elegante y eficiente que la solución alternativa propuesta. No dude en explorar los fragmentos de código proporcionados y optimizar el enfoque según sus requisitos específicos.

Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3