Я пытаюсь использовать Unmarshal
method из пакета frontmatter для анализа фронт-материала из файла уценки.Интерфейс с неизвестными свойствами
Сигнатура типа для функции выглядит следующим образом
func Unmarshal(data []byte, v interface{}) (err error)
У меня есть данные байт, и я понимаю, что мне нужно передать интерфейс/с-структуру соответствующих полей в качестве второго аргумента, однако я не знаю, какие поля будут в файлах, которые я анализирую, и важно, чтобы я не потерял данные.
Внутренне этот пакет использует yaml.v2, который представляет собой более подробный пример определения интерфейса перед немедленной сортировкой.
type T struct {
A string
B struct {
RenamedC int `yaml:"c"`
D []int `yaml:",flow"`
}
}
Затем создайте экземпляр структуры t
и передать указатель на t
до Unmarshal
.
t := T{}
err := yaml.Unmarshal([]byte(data), &t)
Как я понимаю, это будет работать только если YAML выглядит следующим образом:
a: Easy!
b:
c: 2
d: [3, 4]
Второй пример выглядит ближе к тому, что мне нужно. Вместо создания структуры, похоже, используется карта interface{} -> interface{}
.
m := make(map[interface{}]interface{})
err = yaml.Unmarshal([]byte(data), &m)
Я относительно новым Пойти и мне это выглядит как родовая карта, которая бы идеально подходит для чтения в неизвестных значениях.
Я адаптировал пример для своего собственного проекта и получил следующий код.
m := make(map[interface{}]interface{})
err := frontmatter.Unmarshal(data, &m)
Но это приводит к ошибке во время выполнения
panic: reflect: NumField of non-struct type
Полный StackTrace here.
Я направляюсь в правильном направлении? Если да, то что происходит не так?
Я не могу по-настоящему помочь вам, поскольку я не играл с этими пакетами, но с быстрым взглядом frontmatter.Unmarshal, похоже, не делает никаких проверок, является ли второй аргумент структурой или нет, но он вызывает отражение .NumField на нем, который будет паниковать на неструктурах. Я предполагаю, что вам придется искать другой путь, если вы хотите развязать карту. – Aedolon
'frontmatter' предполагает, что вы передадите указатель на структуру, но на самом деле не проверяете, так это.Я бы советовал о лучшей, более надежной обобщенной реализации, если есть один доступный. – thwd
Но 'frontmatter' на самом деле ничего не делает с самим указателем, он просто [переводит его на' yaml.Unmarshal'] (https://github.com/ericaro/frontmatter/blob/master/frontmatter.go# L73), который, как показано, берет карту в примере. –