转到转换界面{}以映射

时间:2019-04-19 02:40:40

标签: go

我正在将接口{}转换为map [string] string。

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    data := `{"1":"2", "3": "4"}`
    var v interface{}
    json.Unmarshal([]byte(data), &v)
    fmt.Printf("%+v\n", v)
    _, ok := v.(map[string]interface{})
    fmt.Printf("%v\n", ok)
    _, ok = v.(map[string]string)
    fmt.Printf("%v\n", ok)
    _, ok = v.(map[interface{}]interface{})
    fmt.Printf("%v\n", ok)
}

代码在这里https://play.golang.org/p/I_clyMdaGzw

为什么map [string] interface {}可以,但是map [string] string,map [interface {}] interface {}不起作用?

2 个答案:

答案 0 :(得分:2)

https://godoc.org/encoding/json#Unmarshal

To unmarshal JSON into an interface value, Unmarshal stores one of these in the interface value:

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

由于使用interface{}进行解码,因此json对象的默认类型为map[string]interface{}

答案 1 :(得分:1)

json对象解组到mapinterface将始终使用map[string]interface{}解组JSON对象(如他的回答中提到的beiping96)。

使用reflect.TypeOf查看变量的类型。您只能将其投射为该类型。如果您想要其他类型,则需要转换

下面是进入map[string]string的示例:

func main() {
    data := `{"1":"2", "3": "4"}`
    var v interface{}
    if err := json.Unmarshal([]byte(data), &v); err != nil {
        log.Fatal(err)
    }

    var res = map[string]string{}
    for k, v := range v.(map[string]interface{}) {
        res[k] = v.(string)
    }
    fmt.Println(reflect.TypeOf(res), res)
}

注意:我假设结构是已知的,并且不检查类型。如果类型与假定的不同,这将引起恐慌。使用您用来防止恐慌的val, ok := ...模式。

但是,以上并不是取消元帅到map[string]string的惯用方式。通常的方法(如果您知道JSON字符串的结构)是让json包处理类型转换:

func main() {
    data := `{"1":"2", "3": "4"}`
    var res map[string]string
    if err := json.Unmarshal([]byte(data), &res); err != nil {
        log.Fatal(err)
    }

    fmt.Println(reflect.TypeOf(res), res)
}