json unmarshal generic interface{}

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

json unmarshal generic interface{}

问题

以下是翻译好的内容:

http://blog.golang.org/json-and-go

m := j.(map[string]interface{}) 对我来说不起作用

panic: 接口转换: interface {} 是 []interface {},而不是 map[string]interface {}

所以我最终用这样的代码使其工作?不认为这是正确的做法 json unmarshal generic 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 json unmarshal generic 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, "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.

huangapple
  • 本文由 发表于 2016年1月11日 04:21:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/34710357.html
匿名

发表评论

匿名网友

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

确定