Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

golang 解析json问题

{
    "method": "update",
    "params": ["TODOS", [{
        "id": 275570305,
        "time": 1598273441.8892069,
        "type": "myid"
    }]]
}

该段json使用golang解析失败, golang代码:


    var mapTick struct {
        Method string        `json:"method"`
        Params []interface{} `json:"params"`
    }
    type Param []struct {
        ID     int64   `json:"id"`
        Time   float64 `json:"time"`
        Type   string  `json:"type"`
    }

    err := json.Unmarshal([]byte(jsonstr), &mapTick)
    if err != nil {
        fmt.Println(err)
    } else {
        if len(mapTick.Params) == 2 {
            fmt.Println(mapTick.Params[1])
            if _ , ok := mapTick.Params[1].(Param); ok {
                res := mapTick.Params[1].(Param)
                fmt.Println(res)
            }
        }
    }

除了我这种代码, 还有更好的解析方法吗?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
if _ , ok := mapTick.Params[1].(Param); ok {

这个地方不对,可以用reflect.Typeof(mapTick.Params[1])来查看其类型,其实并不是Param

另外定义结构体的时候,最好不要定义为数组:type Param []struct {
可读性太差,自己也容易记错

我改写了下,可以参考:

package main

import (
    "encoding/json"
    "fmt"
    "errors"
)

type Param struct {
    ID   int64   `json:"id"`
    Time float64 `json:"time"`
    Type string  `json:"type"`
}

type Tick struct {
    Method string
    Params struct {
        Todo string
        Arr  []Param
    }
}

func (t *Tick) UnmarshalJSON(data []byte) error {
    mapTick := struct {
        Method string        `json:"method"`
        Params []interface{} `json:"params"`
    }{}

    err := json.Unmarshal(data, &mapTick)
    if err != nil {
        return err
    }

    t.Method = mapTick.Method

    if len(mapTick.Params) == 2 {
        for _, tick := range mapTick.Params {
            if _, ok := tick.(string); ok {
                t.Params.Todo = tick.(string)
            }

            if ps, ok := tick.([]interface{}); ok {
                for _, p := range ps {
                    if _, ok := p.(map[string]interface{}); ok {
                        param := Param{}
                        kv := p.(map[string]interface{})
                        param.ID = (int64)(kv["id"].(float64))
                        param.Time = kv["time"].(float64)
                        param.Type = kv["type"].(string)
                        t.Params.Arr = append(t.Params.Arr, param)
                    } else {
                        return errors.New("Tick UnmarshalJSON failed.")
                    }
                }
            }
        }
    }

    return nil
}

func main() {
    jsonstr := `{
        "method": "update",
        "params": ["TODOS", [{
        "id": 275570305,
        "time": 1598273441.8892069,
        "type": "myid"
        }]]
        }`

    myTick := Tick{}
    err := json.Unmarshal([]byte(jsonstr), &myTick)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(myTick)
}

输出如下:
{update {TODOS [{275570305 1.598273441889207e+09 myid}]}}

Tick的结构需要根据实际情况定义,这里是我根据你现有json定义的,可以自行修改。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...