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.
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