Чтобы разобрать набор типов, которые все реализуют общий интерфейс, вы можете реализовать интерфейс json.Unmarshaler
для родительского типа, map[string]CustomInterface
в вашем случае:
type CustomInterfaceMap map[string]CustomInterface
func (m CustomInterfaceMap) UnmarshalJSON(b []byte) error {
data := make(map[string]json.RawMessage)
if err := json.Unmarshal(b, &data); err != nil {
return err
}
for k, v := range data {
var dst CustomInterface
// populate dst with an instance of the actual type you want to unmarshal into
if _, err := strconv.Atoi(string(v)); err == nil {
dst = &CustomImplementationInt{} // notice the dereference
} else {
dst = &CustomImplementationFloat{}
}
if err := json.Unmarshal(v, dst); err != nil {
return err
}
m[k] = dst
}
return nil
}
Полный пример см. На этой площадке .Убедитесь, что вы отменяете маршализацию в CustomInterfaceMap
, а не map[string]CustomInterface
, в противном случае пользовательский метод UnmarshalJSON
вызываться не будет.
json.RawMessage
- это полезный тип, который простонеобработанное закодированное значение JSON, то есть это простое []byte
, в котором JSON хранится в неразобранной форме.