json unmarshal generic interface {}

时间:2016-01-10 20:21:24

标签: go

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

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

panic: interface conversion: interface {} is []interface {}, not 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, "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")
        }
    }

编辑:我尝试使其不可读

    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:工作但仍然很难看

    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 个答案:

答案 0 :(得分:3)

似乎JSON代码的根部分是JSON数组(["item", "item", {"key": "value"}]表示法)。虽然有些JSON库不喜欢它,但JSON blob的“根”可以是数组而不是对象({"key": "value"}表示法)。

在生产应用程序中,您应该使用类型断言的第二个值来确保它是正确的类型:

m, mOk := j.(map[string]interface{})
s, sOk := j.([]interface{})

if mOk {
    // Use Map
} else {
    // Use Slice
}

如果您不需要编辑数据, Jason 是Go的绝佳图书馆。