恐慌:接口转换错误:接口{}是[]interface{},而不是map[string]interface{}。

huangapple go评论71阅读模式
英文:

panic: interface conversion: interface {} is []interface {}, not map[string]interface {}

问题

我有一个简单的GO程序来解析JSON:

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	jsonData := `{"aaa": {"bbb": {"ccc": [{"file_1": "file.jpg", "file_2": "file.png"}]}}}`

	var result map[string]map[string]map[string]interface{}
	json.Unmarshal([]byte(jsonData), &result)

	files := result["aaa"]["bbb"]["ccc"].(map[string]interface{})

	for key, value := range files {
		fmt.Println(key, value)
	}
}

我想要获取文件列表,所以输出应该是:

file_1 file.jpg
file_2 file.png

但是这段代码给我返回了错误:

panic: interface conversion: interface {} is []interface {}, not map[string]interface {}

我做错了什么?

英文:

I have simple program in GO to parse JSON:

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	jsonData := `{"aaa": {"bbb": {"ccc": [{"file_1": "file.jpg", "file_2": "file.png"}]}}}`

	var result map[string]map[string]map[string]interface{}
	json.Unmarshal([]byte(jsonData), &result)

	files := result["aaa"]["bbb"]["ccc"].(map[string]interface{})

	for key, value := range files {
		fmt.Println(key, value)
	}
}

https://go.dev/play/p/dxv8k4pI7uX

I would like to receive list of files, so response should be:

> file_1 file.jpg
> file_2 file.png

but this code return me error:

panic: interface conversion: interface {} is []interface {}, not map[string]interface {}

What I'm doing wrong?

答案1

得分: 1

result["aaa"]["bbb"]["ccc"]的类型是[]interface{},因为JSON中有一个映射的数组。

一种解决方案是更改result的声明以匹配JSON模式:

var result map[string]map[string]map[string][]map[string]string

或者,您可以保留interface{}的定义,但是您需要在每个级别上进行额外的类型断言:

var result map[string]map[string]map[string]interface{}
json.Unmarshal([]byte(jsonData), &result)

fileList := result["aaa"]["bbb"]["ccc"].([]interface{})

for _, fileI := range fileList {
    for key, value := range fileI.(map[string]interface{}) {
        fmt.Println(key, value.(string))
    }
}

编辑:这第二种方法与上面评论中的@icza的方法相同。

英文:

The type of result["aaa"]["bbb"]["ccc"] is []interface{} since the json has an array of maps.

One solution is to change the declaration of result to match the json schema:

var result map[string]map[string]map[string][]map[string]string

Alternatively, you can keep your definition of interface{} but then you have additional steps to do the type asserts at each level:

var result map[string]map[string]map[string]interface{}
json.Unmarshal([]byte(jsonData), &result)

fileList := result["aaa"]["bbb"]["ccc"].([]interface{})

for _, fileI := range fileList {
    for key, value := range fileI.(map[string]interface{}) {
        fmt.Println(key, value.(string))
    }
}

Edit: This 2nd approach is the same as @icza's in the comment above.

huangapple
  • 本文由 发表于 2022年10月18日 01:57:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/74101312.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定