Skip to content

JSON Unmarshal: обработка сложных данных

Если JSON содержит сложные данные, такие как object или array, то структура должна объявить поля соответствующих типов, чтобы демаршалировать JSON без ошибки.

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

В приведенной выше программе мы объявили тип структуры Profile и изменили структуру Student, чтобы она содержала поле Profile типа Profile.

Мы также ввели несколько новых полей в тип Student структуры array и slice структуру map данных. Мы также предоставили данные JSON для этих полей в значении data.

Еще одна дополнительная вещь, которую мы сделали —  инициализация структуры john некоторыми значениями полей. Мы инициализировали поле Subjects типа данных slice и поле Grades типа данных map. Эта программа выдаст следующий результат.

На этом этапе происходит много событий, поэтому давай пройдемся по результату.

  1. Поля, которые не экспортированы в structJSON или отсутствуют в JSON, не демаршалируются . Если значение поля в JSON равно null и нулевое значение соответствующего типа поля равно nil, (например, interface, map, pointer, или slice, то значение заменяется на nil, в противном случае это поле игнорируется и сохраняет исходное значение.

  2. Если Unmarshal встречается тип array и значения массива в JSON больше, чем может содержать массив, лишние значения отбрасываются. Если значения массива в JSON меньше длины массива, то остальные элементы массива устанавливаются в свои нулевые значения. Тип должен быть array совместим со значениями в JSON.

  3. Если в Unmarshal встречается тип slice, то для slice в struct устанавливается нулевая длина, а элементы из массива JSON добавляются по одному. Если JSON содержит пустой массив, то Unmarshal заменяет slice в struct на пустой slice. Тип slice должен быть совместим со значениями в JSON.

  4. Если в Unmarshal встречается тип map и значение карты в поле struct равно nil, создается новый объект map и добавляются значения объекта в JSON. Если значение map равно non-nil, то повторно используется исходное значение map и добавляются новые записи. Тип map должен быть совместим со значениями в JSON.

Если в Unmarshal встречается поле указателя и значение этого поля в JSON равно null, то этому полю присваивается значение указателя nil. Если поля в JSON не null, то для указателя выделяется новая память на случай, если указатель является nil либо повторно используется старое значение указателя.

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

В приведенной выше программе Subject для поля задано явное значение nil. Поле Profile структуры Student содержит указатель на тип Profile и инициализируется значением поля Username.

В данных JSON мы установили поля Grades в значение null. Мы также предоставили значение поля Profile.Followers. Посмотрим на результат этой программы.

Как видно из результата, значение поля массива Languages было переопределено значениями в JSON. Поле Grades стало nil, потому что это поле map (и его нулевое значение равно nil) и значение в JSON равно null.

Поскольку поле Profile является указателем, а его значение в структуре john равно non-nil, Unmarshal использует существующее значение указателя и назначенные значения поля из JSON. Если значение поля Profile в JSON было null, то john было бы безоговорочно установлено значение поля Profile nil.