"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 los campos Yaml a un conjunto finito de estructuras en GO?

¿Cómo analizar dinámicamente los campos Yaml a un conjunto finito de estructuras en GO?

Publicado el 2025-03-13
Navegar:651

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

dinámicamente los campos Yaml a un conjunto finito de estructuras en Go

analizar archivos Yaml es una tarea común en muchas aplicaciones. Sin embargo, a veces un archivo YAML puede contener campos que deben estar representados por diferentes tipos de estructuras. Esto puede conducir a un código complejo y archivos Yaml desordenados.

, por ejemplo, considere los siguientes archivos YAML:

kind: "foo"
spec:
  fooVal: 4
kind: "bar"
spec:
  barVal: 5

y las estructuras correspondientes para analizar:

type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"spec"`
}

type Foo struct {
    FooVal int `yaml:"fooVal"`
}

type Bar struct {
    BarVal int `yaml:"barVal"`
}

Un enfoque es usar una interfaz MAP [String] {} como el tipo para el campo Spec. Sin embargo, este enfoque puede conducir a una complejidad y consumo de memoria adicional, especialmente para grandes archivos Yaml.

una solución más elegante es usar la estructura yamlnode:

type yamlNode struct {
    unmarshal func(interface{}) error
}

func (n *yamlNode) UnmarshalYAML(unmarshal func(interface{}) error) error {
    n.unmarshal = unmarshal
    return nil
}

y modifique la estructura de especificaciones para usarlo:

type Spec struct {
    Kind string      `yaml:"kind"`
    Spec interface{} `yaml:"-" json:"-"`
}

con estos cambios, la función unmarshalyaml para especific puede analizar dinámicamente y unmarshal el campo de especificaciones en un tipo de estructura específico:

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

Este enfoque proporciona una solución más elegante y eficiente para analizar dinámicamente los campos Yaml en un conjunto finito de estructuras, lo que hace que su código y los archivos YAML sean mucho más limpios y más fáciles de administrar.

Ú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