Мне, наконец, удалось заставить его работать с безобразным обходным путем.
Я изменил свою структуру на
type Stats struct {
Status int `json:"status"`
Date string `json:"date"`
Title string `json:"title"`
Devices interface{} `json:"devices"`
Refs interface{} `json:"refs"`
}
Тогда я, наконец, могу демаршировать JSON в обоих случаях, но я получаю map[string]interface{}
при передаче объекта и пустое interface{}
при пропуске пустого массива. Чтобы устранить это несоответствие, я просто проверяю тип данных и принудительно использую промежуточное преобразование JSON, чтобы распаковать значение map[string]interface{}
внутри пользовательской Devices
struct:
// Devices contains devices information
type Devices struct {
Dev []struct {
Tag string `json:"tag"`
Clicks string `json:"clicks"`
} `json:"dev"`
Sys []struct {
Tag string `json:"tag"`
Clicks string `json:"clicks"`
} `json:"sys"`
Bro []struct {
Tag string `json:"tag"`
Clicks string `json:"clicks"`
} `json:"bro"`
}
Я использую следующие алгоритмы:
//ForceDevicesToRightType uses a json conversion as intermediary for filling the Stats.Devices
// struct with map[string]interface{} values
func ForceDevicesToRightType(dev interface{}) (Devices, error) {
temp, err := json.Marshal(dev)
if err != nil {
return Devices{}, err
}
// Use a temporary variable of the right type
var devices Devices
err = json.Unmarshal(temp, &devices)
if err != nil {
return Devices{}, err
}
return devices, nil
}
// ForceRefsToRightType uses a json conversion as intermediary for filling the Stats.Refs
// struct with map[string]interface{} values
func ForceRefsToRightType(refs interface{}) (Refs, error) {
temp, err := json.Marshal(refs)
if err != nil {
return Refs{}, err
}
// Use a temporary variable of the right type
var references Refs
err = json.Unmarshal(temp, &references)
if err != nil {
return Refs{}, err
}
return references, nil
}
Поскольку компилятор знает, что поля Devices и Refs interface{}
, я не могу просто получить доступ к каким-либо методам после преобразования, поэтому я просто делаю приведение правильного типа, и все работает нормально.
Например, если я хотел получить доступ к подструктуре Dev, это правильный путь:
y, _ := GetStats()
fmt.Println(y.Devices.(Devices).Dev)
Это некрасиво, но работает.
Большое спасибо за вашу помощь, я надеюсь, что этот метод избавит вас от головной боли!