Основы маршалинга и демаршалинга JSON
JSON означаетJavaScriptНотация объектов, и это очень удобный способ обмена структурированными данными. И это очень популярно, особенно при взаимодействии с API.
Go имеет поддержку верхнего уровня для JSON в своей стандартной библиотеке свencoding/json
упаковка.
По сравнению со слабо типизированными языками декодирование JSON сложнее. В JavaScript все, что вам нужно сделать, этоJSON.parse()
. Python имеетjson.loads()
, а в PHP естьjson_decode()
. Они просто сбрасывают значения без проблем, но, поскольку Go строго типизирован, вам нужно проделать немного больше работы, чтобы сопоставить типы.
JSON имеет 3 основных типа:булевы,числа,струны, в сочетании с использованиеммассивыиобъектыстроить сложные конструкции.
Терминологические вызовы Goмаршалпроцесс генерации строки JSON из структуры данных, идемаршалакт синтаксического анализа JSON в структуру данных.
Строка JSON
input := `{"firstname": "Bill", "surname": "Gates"}`
Unmarshal JSON
Вот пример JSON, взятый изMDN Mozilla
{
"squadName": "Super hero squad",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"members": [
{
"name": "Molecule Man",
"age": 29,
"secretIdentity": "Dan Jukes",
"powers": [
"Radiation resistance",
"Turning tiny",
"Radiation blast"
]
},
{
"name": "Madame Uppercut",
"age": 39,
"secretIdentity": "Jane Wilson",
"powers": [
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes"
]
},
{
"name": "Eternal Flame",
"age": 1000000,
"secretIdentity": "Unknown",
"powers": [
"Immortality",
"Heat Immunity",
"Inferno",
"Teleportation",
"Interdimensional travel"
]
}
]
}
Как мы можем преобразовать его в структуру данных Go? Конечно, нам нужна соответствующая структура данных. У нас есть 5 основных типов и массив объектов. Начнем с основных типов:
type squad struct {
SquadName string
HomeTown string
Formed int
SecretBase string
Active bool
}
Нам нужно определить JSON как[]byte
, так:
input := []byte(`
{
"squadName": "Super hero squad",
[...]
}
`)
И мы можем демаршалировать JSON в экземпляр отряда:
s := squad{}
err := json.Unmarshal(input, &s)
if err != nil {
panic(err)
}
fmt.Printf("%v", s)
Это напечатает
{Super hero squad Metro City 2016 Super tower true}
Обратите внимание, что у нас нет ошибок, связанных с отсутствием соответствия между значениями JSON и нашей структурой, они игнорируются.
Давайте удостоверимся, что json.Unmarshal () получит все поля:
type squad struct {
SquadName string
HomeTown string
Formed int
SecretBase string
Active bool
Members []Member
}
type Member struct {
Name string
Age int
SecretIdentity string
Powers []string
}
Не забудьте, что в ваших структурах должны быть публичные (прописные) свойства.
Переименование имен полей JSON
В этом случае все было хорошо, потому что у JSON были совместимые имена файлов. Что, если вы хотите сопоставить JSON с другими полями в вашей структуре?
Например, что, если имя участника передается какmember_name
, но вы хотите, чтобы он хранился вName
вместо?
Используйте этот синтаксис:
type Member struct {
Name string `json:"member_name"`
}
Игнорирование полей JSON
Используйте этот синтаксис:
type Member struct {
Name string `json:"-"`
}
и поле Name будут игнорироваться при маршалинге / демаршалинге.
Преобразование типов полей JSON
Вы можете использовать теги для аннотирования типа, в который будет преобразован JSON:
type Member struct {
Age int `json:"age,string"`
}
Структура члена имеетAge
собственность, представленная какint
. Что, если вы хотите, чтобы это былstring
вместо этого, но JSON передаетint
?
Используйте аннотацию типа:
type Member struct {
Age json.Number `json:"age,Number"`
}
Тип Number - это псевдоним дляstring
.
Узнайте больше о тегах вОбъяснение тегов Go
Маршал JSON
Теперь мы можем захотеть построить строку JSON из наших структур данных. Например, это может быть программа, которая принимает код страны и возвращает соответствующие сведения о стране в формате JSON.
package main
import (
“encoding/json”
“fmt”
)
type country struct {
Name string
}
func main() {
country_code := “US”
<span style="color:#a6e22e">the_country</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">country</span>{}
<span style="color:#66d9ef">switch</span> <span style="color:#a6e22e">country_code</span> {
<span style="color:#66d9ef">case</span> <span style="color:#e6db74">"US"</span>:
<span style="color:#a6e22e">the_country</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#e6db74">"United States"</span>
}
<span style="color:#a6e22e">c</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Marshal</span>(<span style="color:#a6e22e">the_country</span>)
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
panic(<span style="color:#a6e22e">err</span>)
}
<span style="color:#75715e">// c is now a []byte containing the encoded JSON
fmt.Print(string(c))
}
При выполнении эта программа напечатает{"Name":"United States"}
.
json.Marshal()
возвращает[]byte
, поэтому мы должны преобразовать его в строку при передаче вfmt.Print()
, в противном случае вы увидите список явно бессмысленных чисел (но они имеют смысл, поскольку являются фактическими байтами, составляющими строку).
json.Marshal()
будет правильно обрабатывать базовые и композитные типы, такие как срезы и карты.
Прочитайте больше
Прочитайте большев блоге GoИ ввencoding/json
пакет документов
Больше руководств по go:
- Использование обратного прокси NGINX для обслуживания сервисов Go
- Создание копии структуры в Go
- Основы веб-сервера Go
- Сортировка типа карты в Go
- Вкратце об указателях Go
- Объяснение тегов Go
- Форматирование даты и времени Go
- Обработка JSON с помощью Go
- Перейти к переменным функциям
- Шпаргалка по струнам Go
- Объяснение интерфейса Go Empty
- Отладка Go с помощью VS Code и Delve
- Именованный Go возвращает параметры
- Генерация случайных чисел и строк в Go
- Структура файловой системы проекта Go
- Алгоритм двоичного поиска, реализованный в Go
- Использование флагов командной строки в Go
- GOPATH объяснил
- Создайте приложение командной строки с помощью Go: lolcat
- Создание команды интерфейса командной строки с помощью Go: cowsay
- Использование Shell Pipes с Go
- Учебник по интерфейсу командной строки: Fortune Clone
- Перечислить файлы в папке с помощью Go
- Используйте Go, чтобы получить список репозиториев с GitHub
- Пойдите, добавьте фрагмент строк в файл
- Пойдите, преобразуйте строку в срез байтов
- Визуализируйте свой вклад в Git с помощью Go
- Начало работы с Go CPU и профилирование памяти
- Устранение ошибки "не поддерживает индексацию" в программе Go
- Измерение времени выполнения в программе Go
- Создание веб-краулера с Go для обнаружения повторяющихся заголовков
- Go Best Practices: указатель или приемники значений?
- Go Best Practices: следует ли использовать метод или функцию?
- Структуры данных Go: установить
- Шпаргалка по картам Go
- Создание реализаций для универсальных типов в Go
- Структуры данных Go: словарь
- Структуры данных Go: хеш-таблица
- Реализуйте прослушиватели событий в проходных каналах
- Структуры данных Go: стек
- Структуры данных Go: очередь
- Структуры данных Go: двоичное дерево поиска
- Структуры данных Go: график
- Структуры данных Go: связанный список
- Полное руководство по структурам данных Go
- Сравнение значений Go
- Является ли Go объектно-ориентированным?
- Работа с базой данных SQL в Go
- Использование переменных среды в Go
- Учебник: REST API на базе PostgreSQL
- Включение CORS на веб-сервере Go
- Развертывание приложения Go в контейнере Docker
- Почему Go - мощный язык для изучения PHP-разработчика
- Пойдите, удалите символ новой строки io.Reader.ReadString
- Идите, как посмотреть изменения и пересобрать вашу программу
- Иди, посчитай месяцы с даты
- Доступ к параметрам HTTP POST в Go