go 花式 json 转换

1,881 阅读2分钟
原文链接: kuanshijiao.com

确定类型变换

package main
import (
    "encoding/json"
    "fmt"
)
type F struct {
    H string
    K int
}
type A struct {
    B string
    C int
    D map[string]int
    E []int
    F F
}
func main() {
    txt := `{"b":"hello word","c":1,"d":{"a":1,"b":2},"e":[2,3,4,5],"f":{"h":"a","k":1}}`
    var ab A
    json.Unmarshal([]byte(txt), &ab)
    fmt.Println(ab.B)
    fmt.Println(ab.C)
    for key, val := range(ab.D){
        fmt.Println(key, val)
    }
    for _, e := range(ab.E){
        fmt.Println(e)
    }
    fmt.Println(ab.F.H)
    fmt.Println(ab.F.K)
}

确定类型的转换,需要明确知道json文档会转成什么类型,可以嵌套,可以是自定义类型。比较适合文档数据库的模型对接。

不确定类型变换

package main
import (
    "encoding/json"
    "fmt"
)
func Decode(obj map[string]interface{}){
    for k, v := range obj {
        switch vv := v.(type) {
        case string:
            fmt.Println(k, "is string", vv)
        case int:
            fmt.Println(k, "is int", vv)
        case float64:
            fmt.Println(k,"is float64",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")
        }
    }
}
func main() {
    txt := `{"a":1,"b":"hello","c":{"a":1,"b":2.5},"d":["a","b","c"]}`
    var ab map[string]interface{}
    json.Unmarshal([]byte(txt), &ab)
    Decode(ab)
}

不确定类型的转换,不用知道json文档会转成什么类型,可以通过类型推断value.(type)或者reflect.ValueOf(value)搭配switch使用,不太好的是每个解析转换地方都要编码。

递归模型变换

package main
import (
    "encoding/json"
    "fmt"
)
func JsonDecode(str []byte) map[string]interface{} {
    var dict map[string]interface{}
    err := json.Unmarshal(str, &dict)
    if err != nil {
        fmt.Println(err)
        return nil
    }
    return dict
}
func JsonEncode(dict interface{}) []byte {
    str, err := json.Marshal(dict)
    if err != nil {
        fmt.Println(err)
        return nil
    }
    println(string(str))
    return str
}
type A struct {
    B string
    C int
    D *A
}
func main() {
    var a A
    var hk A
    a = A{
        B:"hello word!",
        C:1,
        D:&A{
            B:"hello ABC",
            C:2,
            D:nil,
        },
    }
    fmt.Println(a.B)
    str, _ := json.Marshal(a)
    println(string(str))
    json.Unmarshal(str, &hk)
    fmt.Println(hk.D.B)
}

递归类型的转换,允许深度的层次扩增,不允许广度的动态类型。

静态语言和动态语言的在json处理上体现的非常明显,动态语言处理实在太方便了,即开即用,而静态语言处理就比较吃力,但是实际上开发的时候,应该用确定的东西,尽量避开不确定,一劳永逸,类型推断方便使用的时候确定数据类型,递归模型处理还是不错的,某些特定场景很有用。