Skip to content

JSON Unmarshal: работа с картами

Поскольку JSON содержит ключи string  и значения поддерживаемых типов данных, тип map типа map[string]interface{} является подходящим кандидатом для хранения данных JSON. Мы можем передать указатель на функцию nil или non-nil указатель на map функцию Unmarshal, и все значения полей JSON будут заполнены внутри файла map.

Пришло время поработать с кодом!

В приведенном выше примере мы создали map типов данных Student, которая содержит ключи string типов данных и значения типов данных interface{}. Если JSON содержит значения определенного типа данных, мы можем настроить тип данных map в соответствии с ним, например, map[string]float64 для целочисленных значений JSON.

Мы создали пустую map переменную john, которая имеет значение nil в данный момент. Мы передали указатель john на функцию Unmarshal, и эта функция инициализирует map для хранения декодированных данных JSON.

Из приведенного выше результата мы видим, что все поля были заполнены внутри map john. Но взгляни на типы данных значений map. Существуют определенные правила Unmarshal, которым следуют функции для хранения значений JSON в файле map.

  1. Значение JSON string сохраняется как string.

  2. Значение JSON number( int или float) сохраняется как float64.

  3. Значение JSON boolean сохраняется как bool.

  4. Значение JSON null сохраняется как nil значение.

  5. Значение JSON array хранится как slice тип []interface{}.

  6. Значение JSON object хранится как map тип map[string]interface{}.

В результате интересно посмотреть на значения JSON array и object. Значения array были сохранены в slice типе, а []interface{} и object значения сохранены в map типе map[string]interface{}.

Как мы знаем, допустимым форматом JSON может быть object, как в примере выше, или array. Поскольку Unmarshal способен выделять память для указателя, а также может создавать контейнеры для хранения декодированных данных JSON самостоятельно, мы можем хранить сложные данные JSON без определения типа контейнера.

Пришло время поработать с кодом!

В приведенном выше примере мы создали контейнер john типа interface{}. Его значение по умолчанию — nil, потому что на данный момент интерфейс не имеет конкретного значения. Мы передаем указатель интерфейса john в качестве аргумента функции Unmarshal.

Функция Unmarshal извлечет конкретное значение интерфейса, и если найдет его nil, назначит ему подходящий тип данных для хранения декодированных данных JSON. Программа выше дает следующий результат.

Как видно из приведенного выше результата, функция Unmarshal сохранила map, если тип map[string]interface{} является конкретным значением интерфейса. Если бы JSON был array вместо object, он сохранил бы slice тип []interface как конкретное значение.

Помни, что сейчас john — это интерфейс, и для доступа к значениям map нам сначала нужно извлечь конкретное значение интерфейса. Для этого нужно использовать синтаксис утверждения типа interface.(Type).