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

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

Опубликовано 8 ноября 2024 г.
Просматривать:120

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

Динамический анализ YAML-поля в конечный набор структур в Go

Введение

Разбор YAML в структуру в Go может быть простым. Однако, когда поле YAML может представлять несколько возможных структур, задача усложняется. В этой статье рассматривается динамический подход с использованием пакета YAML Go.

Динамическое демаршалинг с YAML v2

Для Yaml v2 можно использовать следующий подход:

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

Динамическая демаршалинг с помощью YAML v3

Для Yaml v3 подход немного другой:

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

Заключение

Эти методы динамического демаршалинга позволяют гибко анализировать поля YAML в конечный набор структур, обеспечивая более элегантное и эффективное решение, чем предлагаемый обходной путь. Не стесняйтесь изучать предоставленные фрагменты кода и оптимизировать подход в соответствии с вашими конкретными требованиями.

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

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

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

Copyright© 2022 湘ICP备2022001581号-3