英文:
json unmarshal generic interface{}
问题
以下是翻译好的内容:
http://blog.golang.org/json-and-go
m := j.(map[string]interface{})
对我来说不起作用
panic: 接口转换: interface {} 是 []interface {},而不是 map[string]interface {}
所以我最终用这样的代码使其工作?不认为这是正确的做法
var j interface{}
err = json.Unmarshal(b, &j)
if err != nil {
log.Print(err.Error())
}
m := j.([]interface{}) //map[string]interface{}
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "是字符串", vv)
case int:
fmt.Println(k, "是整数", vv)
case []interface{}:
fmt.Println(k, "是数组:")
for i, u := range vv {
fmt.Println(i, u)
}
case map[string]interface{}:
for k2, v2 := range v.(map[string]interface{}) {
switch vv2 := v2.(type) {
case string:
fmt.Println(k2, "是字符串", vv2)
case int:
fmt.Println(k2, "是整数", vv2)
case []interface{}:
fmt.Println(k2, "是数组:")
for i2, u2 := range vv2 {
fmt.Println(i2, u2)
}
default:
fmt.Println(k2, "是我不知道如何处理的类型")
}
}
default:
fmt.Println(k, "是我不知道如何处理的类型")
}
}
编辑:我未能使其可读
var j interface{}
err = json.Unmarshal(b, &j)
if err != nil {
log.Print(err.Error())
}
write(j.([]interface{}))
func write(j []interface{}) {
for k, v := range j {
switch vv := v.(type) {
case string:
fmt.Println(k, "是字符串", vv)
case int:
fmt.Println(k, "是整数", vv)
case []interface{}:
fmt.Println(k, "是数组:")
for i, u := range vv {
fmt.Println(i, u)
}
case map[string]interface{}:
write(v.([]interface{}))
default:
fmt.Println(k, "是我不知道如何处理的类型")
}
}
}
编辑2:虽然能工作但仍然不美观
var j interface{}
err = json.Unmarshal(b, &j)
if err != nil {
log.Print(err.Error())
}
write(j.([]interface{}))
func write(j []interface{}) {
for k, v := range j {
switch vv := v.(type) {
case string:
fmt.Println(k, "是字符串", vv)
case int:
fmt.Println(k, "是整数", vv)
case []interface{}:
fmt.Println(k, "是数组:")
for i, u := range vv {
fmt.Println(i, u)
}
case map[string]interface{}:
write2(v.(map[string]interface{}))
default:
fmt.Println(k, "是我不知道如何处理的类型")
}
}
}
func write2(j map[string]interface{}) {
for k, v := range j {
switch vv := v.(type) {
case string:
fmt.Println(k, "是字符串", vv)
case int:
fmt.Println(k, "是整数", vv)
case []interface{}:
fmt.Println(k, "是数组:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "是我不知道如何处理的类型")
}
}
}
英文:
http://blog.golang.org/json-and-go
m := j.(map[string]interface{})
didn't work for me
panic: interface conversion: interface {} is []interface {}, not map[string]interface {}
So I end up with code like this to make it work? Don't think its the correct way of doing it
var j interface{}
err = json.Unmarshal(b, &j)
if err != nil {
log.Print(err.Error())
}
m := j.([]interface{}) //map[string]interface{}
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
case map[string]interface{}:
for k2, v2 := range v.(map[string]interface{}) {
switch vv2 := v2.(type) {
case string:
fmt.Println(k2, "is string", vv2)
case int:
fmt.Println(k2, "is int", vv2)
case []interface{}:
fmt.Println(k2, "is an array:")
for i2, u2 := range vv2 {
fmt.Println(i2, u2)
}
default:
fmt.Println(k2, "is of a type I don't know how to handle")
}
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
EDIT: My failed attempt to make it readable
var j interface{}
err = json.Unmarshal(b, &j)
if err != nil {
log.Print(err.Error())
}
write(j.([]interface{}))
func write(j []interface{}) {
for k, v := range j {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
case map[string]interface{}:
write(v.([]interface{}))
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
}
EDIT2: Works but still ugly
var j interface{}
err = json.Unmarshal(b, &j)
if err != nil {
log.Print(err.Error())
}
write(j.([]interface{}))
func write(j []interface{}) {
for k, v := range j {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
case map[string]interface{}:
write2(v.(map[string]interface{}))
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
}
func write2(j map[string]interface{}) {
for k, v := range j {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
}
答案1
得分: 3
似乎JSON代码的根部分是一个JSON数组(["item", "item", {"key": "value"}]
表示法)。尽管一些JSON库不喜欢这样做,但JSON blob的“根”可以是一个数组,而不是一个对象({"key": "value"}
表示法)。
在生产应用程序中,您应该使用类型断言的第二个值来确保它是正确的类型:
m, mOk := j.(map[string]interface{})
s, sOk := j.([]interface{})
if mOk {
// 使用Map
} else {
// 使用Slice
}
如果您不需要编辑数据,Go语言中有一个很棒的库叫做Jason。
英文:
It seems as the root part of the JSON code is a JSON array (the ["item", "item", {"key": "value"}]
notation). Although some JSON libraries don't like it, the "root" of the JSON blob can be an array and not an object (the {"key": "value"}
notation).
In a production application, you should use the second value of type assertions to make sure it's the right type:
m, mOk := j.(map[string]interface{})
s, sOk := j.([]interface{})
if mOk {
// Use Map
} else {
// Use Slice
}
If you don't need to edit the data, Jason is a great library for Go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论