«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как динамически анализировать поля YAML в конечный набор структур в Go?

Как динамически анализировать поля YAML в конечный набор структур в Go?

Опубликовано в 2025-03-13
Просматривать:425

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

динамически анализирующий yaml fields в конечный набор структур во многих приложениях

. Однако иногда файл YAML может содержать поля, которые должны быть представлены различными типами структур. Это может привести к сложным коду и загроможденным файлам yaml.

, например, рассмотрите следующие файлы yaml:

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

и соответствующие структуры для анализа:

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"`
}

один подход - использовать интерфейс Map [String] {} в качестве типа для поля Spec. Однако этот подход может привести к дополнительной сложности и потреблению памяти, особенно для больших файлов yaml.

] более элегантное решение - использовать yamlnode struct:

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

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

] и изменить структуру Spec для использования:

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

с этими изменениями, функция Unmarshalyaml для спецификации может динамически проанализировать и Unmarshal поле Spec в определенный тип структуры:

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 в конечный набор структур, делая ваш код и файлы YAML намного чище и проще для управления.

]
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3