Проблема
Найдено много похожих вопросов (название), но ни один из них не решил мою проблему, поэтому вот она.
У меня есть строка JSON, которая содержит некоторые известные поля (должны присутствовать всегда)плюс любое количество неизвестных / произвольных полей.
Пример
{"known1": "foo", "known2": "bar", "unknown1": "car", "unknown2": 1}
В этом примере known1
и known2
являются известными полями.unknown1
и unknown2
- произвольные / неизвестные поля.
Неизвестные поля могут иметь любое имя (ключ) и любое значение.Тип значения может быть либо string, bool, float64, либо int.
Я хочу найти самый простой и изящный (идиоматический) способ для синтаксического анализа сообщения, подобного этому.
Myрешение
Я использовал следующую структуру:
type Message struct {
Known1 string `json:"known1"`
Known2 string `json:"known2"`
Unknowns []map[string]interface{}
}
Ожидаемый результат
С этой структурой и приведенным выше примером сообщения JSON я хочу получить Message
следующее (вывод из fmt.Printf("%+v", msg)
):
{Known1:foo Known2:bar Unknowns:[map[unknown1:car] map[unknown2:1]]}
Попытки
1.Простой немаршал
https://play.golang.org/p/WO6XlpK_vJg
Это не работает, Unknowns
не заполнено оставшимися неизвестными парами ключ / значение, как ожидалось.
2.Двойной unmarshal
https://play.golang.org/p/Mw6fOYr-Km8
Это работает, но мне понадобилось два unmarshals, один для заполнения известных полей (используя тип псевдонима, чтобы избежать бесконечного цикла) и второй для получения всех полейкак map[string]interface{}
и обработать неизвестных.
3.Немаршальное и типовое преобразование
https://play.golang.org/p/a7itXObavrX
Это работает и кажется лучшим вариантом среди моих решений.
Любой другой вариант?
Вариант 2 и 3работать, но мне любопытно, есть ли у кого-нибудь более простое и элегантное решение.