
Как я объединил и проверил два файла JSON в Go
25 июня 2025 г.Когда я начал учиться Go, моей первой реальной задачей было объединить два файла JSON и подтвердить результат. Это звучало легко. Это оказался отличным способом узнать, как GO, ввод -вывод, JSON, MAPS и Type File Randles File.
Вот как я это сделал, что я узнал, и некоторые альтернативы, которые я нашел на этом пути.
Задача
- Прочитайте два файла JSON.
- Объединить их в единую структуру.
- Проверить результат, чтобы убедиться, что определенные поля существуют и имеют правильный тип.
- Напишите окончательный JSON в новый файл.
Шаг 1: чтение файлов JSON
Go имеет отличную поддержку для чтения файлов и декодирования JSON, используя только стандартную библиотеку.
data1, _ := ioutil.ReadFile("file1.json")
data2, _ := ioutil.ReadFile("file2.json")
var json1 map[string]interface{}
var json2 map[string]interface{}
json.Unmarshal(data1, &json1)
json.Unmarshal(data2, &json2)
Примечание: в новых версиях Go вы можете использоватьos.ReadFile
вместоioutil.ReadFile
, сioutil
устарел.
Шаг 2: слияние карт JSON
Мне нужна была функция, чтобы объединить две карты. Если в обеих картах существовал ключ, значение со второй карты должно перезаписать первое. Если значение было вложенным объектом, мне нужно было рекурсивно объединить его.
Вот функция, которую я написал:
func mergeMaps(m1, m2 map[string]interface{}) map[string]interface{} {
for k, v2 := range m2 {
if v1, ok := m1[k]; ok {
if v1Map, ok := v1.(map[string]interface{}); ok {
if v2Map, ok := v2.(map[string]interface{}); ok {
m1[k] = mergeMaps(v1Map, v2Map)
continue
}
}
}
m1[k] = v2
}
return m1
}
Это обработало как плоские, так и вложенные структуры JSON правильно.
Шаг 3: проверка JSON
Затем я написал простую функцию проверки, чтобы проверить, что присутствовали определенные поля и ожидаемого типа. Поскольку я не использовал валидатор схемы, мне пришлось сделать ручные проверки.
func validateJSON(data map[string]interface{}) error {
if _, ok := data["name"].(string); !ok {
return fmt.Errorf("missing or invalid 'name' field")
}
if port, ok := data["port"]; !ok || reflect.TypeOf(port).Kind() != reflect.Float64 {
return fmt.Errorf("missing or invalid 'port' field")
}
return nil
}
Примечание: при расшифровании JSON вinterface{}
цифры рассматриваются какfloat64
по умолчанию, что может сначала сбивать с толку.
Шаг 4: Написание результата
Наконец, я написал объединенный и проверенный JSON обратно в файл, используя красивое форматирование.
resultBytes, _ := json.MarshalIndent(merged, "", " ")
ioutil.WriteFile("merged_output.json", resultBytes, 0644)
Это работало точно так же, как и ожидалось.
Альтернативы: Использование пакета для объединения JSON
Позже я обнаружил, что некоторые пакеты облегчают слияние JSON. Это несколько хороших:
1mergo
mergo
это популярная библиотека для слияния карт и структур в ходе. Он поддерживает вложенные слияния и позволяет выбирать, перезаписать значения.
Установить:
go get github.com/imdario/mergo
Пример:
var a map[string]interface{}
var b map[string]interface{}
json.Unmarshal([]byte(`{"config": {"debug": false}}`), &a)
json.Unmarshal([]byte(`{"config": {"debug": true, "port": 8080}}`), &b)
mergo.Merge(&a, b, mergo.WithOverride)
Используйте это, если вы хотите чисто, глубоко слияние без записи рекурсивного кода.
2json-patch
(Go-Patch)
json-patch
Позволяет применять операции JSON Patch. Это больше для разнообразия и применения структурированных обновлений, но все же полезно для динамической работы с JSON.
Установить:
go get github.com/evanphx/json-patch
Используйте это, если вы работаете с патчами или хотите программно обновить JSON с помощью управления.
3mapstructure
mapstructure
Помогает декодировать динамические карты в сильно напечатанные структуры. Это не инструмент слияния сам по себе, но хорошо работает после того, как вы объединяете данные JSON и хотите связать их с go struct.
Установить:
go get github.com/mitchellh/mapstructure
Используйте это, когда вы хотите структуру и безопасность типа после анализа JSON.
Последние мысли
Эта задача помогла мне многое узнать о том, как GO обрабатывает данные, как работает JSON под капюшоном, и почему сильная печатана имеет значение. Написание функции слияния дало мне контроль, но использование таких библиотек, какmergo
Сделал код более поддерживаемым позже.
Если вы учитесь Go, я рекомендую начать с таких небольших задач. Вы получите реальный опыт работы с файлами, кодированием, картами и обработкой ошибок, при этом решаете практическую проблему.
Это небольшой проект, но тот, который меня многому научил.
Оригинал