2017-01-27 13 views
1

Когда вы отключаете JSON до []interface{}, есть ли способ автоматически определить тип, помимо некоторых стандартных типов, таких как bool, int и string?UnmarshalJSON любой тип из [] интерфейс {} возможно?

То, что я заметил следующее, Скажем, я маршалу [uuid.UUID, bool] тогда JSON я получаю выглядит следующим образом:

[[234,50,7,116,194,41,64,225,177,151,60,195,60,45,123,106],true] 

Когда я распаковать его снова, я получаю типы, как показано через reflect:

[]interface{}, bool

Я не понимаю, почему он выбрал []interface{}. Если он не сможет его обнаружить, не должно быть, по крайней мере, interface{}?

В любом случае, мой вопрос в том, можно ли размонтировать любой тип, если цель имеет тип []interface{}? Кажется, он работает для стандартных типов, таких как string, bool, int, но для пользовательских типов я не думаю, что это возможно, не так ли? Вы можете определить пользовательские методы маршала/немаршала JSON, но это работает только в том случае, если вы декодируете его в целевой тип, чтобы он мог искать, какие пользовательские методы маршала/немаршала использовать.

ответ

3

Вы можете размонтировать любой тип в значение типа interface{}. Если вы используете значение типа []interface{}, в него можно только развернуть массивы JSON, но да, элементы массива могут быть любого типа.

Поскольку вы используете interface{} или []interface{}, да, информация типа недоступна, и это зависит от пакета encoding/json, чтобы выбрать лучшее, что он считает нужным. Например, для объектов JSON он выберет map[string]interface{}. Полный список типов по умолчанию описана в json.Unmarshal():

Чтобы распаковать JSON в значение интерфейса, распаковать хранит одну из них в значении интерфейса:

bool, for JSON booleans 
float64, for JSON numbers 
string, for JSON strings 
[]interface{}, for JSON arrays 
map[string]interface{}, for JSON objects 
nil for JSON null 

Очевидно, что если ваш JSON маршалингом/немаршалирующая логика требует некоторой предварительной/постпроцессинговой обработки, пакет json не будет чудесным образом узнать об этом. Он может знать об этом только в том случае, если вы развязываете значения определенных типов (которые реализуют json.Unmarshaler). Пакет json по-прежнему сможет развязать их по умолчанию, но пользовательская логика, очевидно, не будет работать на них.