Используйте json.Unmarshal
, чтобы преобразовать данные в подходящий тип данных.Во многих случаях вы можете (и я бы порекомендовал) использовать для этой цели объявленные пользователем типы struct
с тегами json
.
Однако, если вы прокомментируете другой ответ, можно разобрать вinterface{}
и пусть unmarshaller определит наиболее подходящий тип данных для представления структуры JSON.Например, срез типа []interface{}
будет представлять список, карту map[string]interface{}
словаря, примитивные типы для их эквивалента JSON и т. Д.
Я написал парсер, который использует этот подход для другого стекавопрос на прошлой неделе.Это не является высокопроизводительным или проверенным кодом, но демонстрирует ключевые моменты:
package main
import (
"encoding/json"
"fmt"
"log"
"reflect"
"strconv"
"strings"
)
// Some arbitrary JSON
const js = `
{
"key1": [
{"key2": false, "some_other_key": "abc"},
{"key3": 3}
],
"key2": {
"hello": "world"
},
"shallow": true,
"null_value": null
}`
func indentStringLines(s string, n int) string {
// Build indent whitespace - this has not been optimized!
var indent string
for i := 0; i < n; i++ {
indent += " "
}
parts := strings.Split(s, "\n")
for i := 0; i < len(parts) - 1; i++ {
parts[i] = indent + parts[i]
}
return strings.Join(parts, "\n")
}
func recursivelyPrintSlice(m []interface{}, indent int) string {
var str string
for i, val := range m {
str += fmt.Sprintf("%s: %s\n",
strconv.FormatInt(int64(i), 10),
recursivelyPrint(val, indent),
)
}
return strings.TrimSpace(str)
}
func recursivelyPrint(val interface{}, indent int) string {
var str string
switch v := val.(type) {
case bool:
str += strconv.FormatBool(v)
case float64:
str += strconv.FormatFloat(v, 'g', -1, 64)
case string:
str += v
case map[string]interface{}:
str += "{\n"
for key, childVal := range v {
str += fmt.Sprintf("%s: %s\n", key, recursivelyPrint(childVal, indent))
}
str += "}"
case []interface{}:
str += "[\n" + recursivelyPrintSlice(v, indent) + "\n]"
case nil:
str += "null"
default:
str += fmt.Sprintf(
"[unimplemented type printer for %s]",
reflect.ValueOf(v).Kind(),
)
}
return strings.TrimSpace(indentStringLines(str, indent+2))
}
func main() {
var x interface{}
err := json.Unmarshal([]byte(js), &x)
if err != nil {
log.Fatal(err)
}
fmt.Println(recursivelyPrint(x, 0))
}