Это началось как просто комментарий на previous answer, но росло.
Хотя вы можете распаковать во временный map[string]interface{}
(или map[string]json.RawMessage
), что может сделать много дополнительной работы, если есть другие «внешние» поля, которые вы просто хотите, чтобы игнорировать, и это также требует проверки типа, который был найден (например, для случая плохого/неожиданного ввода, например {"Outer": 42}
). Это, вероятно, означает, добавив что-то вроде этого к предыдущему ответу:
str, ok := m["Outer"].(string)
if !ok { return errors.New("…") }
err := json.Unmarshal([]byte(str), &actual)
Намного проще, вероятно, использовать временный тип оберточной так:
var tmp struct{ Outer string }
err := json.Unmarshal(b, &tmp)
if err != nil { … }
var data actualType
err := json.Unmarshal([]byte(tmp.Outer), &data)
Вы можете либо сделать это в отдельной функции, возвращает желаемый тип (или ошибку, например func foo(b []byte) (actualType, error)
). Или вы можете поместить это изменение в пользовательский метод UnmarshalJSON
на тип обертки, чтобы реализовать json.Unmarshaler
. Вы также можете сделать обратный, если хотите, чтобы вы могли вернуться в тот же формат.
Полные Runnable примеры на детской площадке: https://play.golang.org/p/IXU2koyJ1A
см http://stackoverflow.com/questions/21268000/unmarshaling-nested-json-objects-in-golang – Makpoc
возможно дубликат http://stackoverflow.com/questions/16674059/how-to-access-deep-nested-json-keys-and-values –