V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
JL1990
V2EX  ›  问与答

golang 中 json 如何解析不同的结构体

  •  
  •   JL1990 · 2022-01-15 20:02:31 +08:00 · 1566 次点击
    这是一个创建于 802 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请教 V 站的大帅 b ,如下代码举例,函数中如何根据传入的不同类型字符串,解析成对应的结构体呢?有没有相关代码可以参考学习的。

    jsonText1 := "{\"name\":\"jack\"}"
    jsonText2 := "{\"age\": 13}"
    
    type V1 struct {
    	Name string	`json:"name"`
    }
    type V2 struct {
    	Age int	`json:"age"`
    }
    
    func parse(jsonString string) (i interface{}) {
    	if err := json.Unmarshal([]byte(jsonText1), &i); err != nil {
    		panic(err)
    	}
    	return
    }
    
    14 条回复    2022-01-15 23:23:03 +08:00
    fishCatcher
        1
    fishCatcher  
       2022-01-15 20:24:44 +08:00 via iPhone
    反射判断一下 json 和 struct 的 tag 哪个能匹配
    wunonglin
        2
    wunonglin  
       2022-01-15 20:24:45 +08:00
    分别解析 V1 、V2 不行?你写的这个 parse 和直接调用 unmarshal 有啥区别
    CodeCore
        3
    CodeCore  
       2022-01-15 20:28:33 +08:00 via iPhone
    转成 map ,再根据 key 的不同赋值给不同的结构体。
    drackzy
        4
    drackzy  
       2022-01-15 21:26:52 +08:00
    只能全部可能的 json 情况都写一遍。不像动态语言。
    CEBBCAT
        5
    CEBBCAT  
       2022-01-15 21:28:43 +08:00
    有很多办法,不管是做一个超集的结构体还是逐个尝试,都是可以的。不过我想问一下,为什么要实现这个功能?拿到 []byte 之前不能确定它的类型吗?
    JL1990
        6
    JL1990  
    OP
       2022-01-15 21:35:37 +08:00
    大概了解了,先转 map ,再根据 map 字段转 struct
    JL1990
        7
    JL1990  
    OP
       2022-01-15 21:37:34 +08:00
    @CEBBCAT #5 我的流程是,收到的这些不同字符串,我想转换成对应的结构体,再做相应的处理。
    CEBBCAT
        8
    CEBBCAT  
       2022-01-15 21:43:54 +08:00
    @JL1990 #7 为什么会有不同类型的数据呢?
    wunonglin
        9
    wunonglin  
       2022-01-15 22:03:42 +08:00
    @JL1990 #7 那为什么不把字段都做在一个 struct ,然后再判断那些有值不就行了么?

    https://s2.loli.net/2022/01/15/4f1JIzoFEKeDp8g.png
    JL1990
        10
    JL1990  
    OP
       2022-01-15 22:18:44 +08:00
    @CEBBCAT #8 我做的是一个公共数据接口,tcp 协议,端口会接收不同的 json 数据字符串,所以对应有不同的数据格式。
    JL1990
        11
    JL1990  
    OP
       2022-01-15 22:19:55 +08:00
    @wunonglin #9 嗯嗯,学到了,你这也是一种方式,感谢指导。
    WilliamYang
        12
    WilliamYang  
       2022-01-15 23:15:24 +08:00
    如何你可以控制数据的格式:
    1. 可以在 json 数据里面最外层放置一个字段表明数据的格式
    2. 增加 tcp 包头,表明数据类型
    walleL
        13
    walleL  
       2022-01-15 23:21:49 +08:00
    @JL1990 #10
    你的接口接收到的数据应该要先区分类型的吧,有一种方式是多嵌套一层 json ,比如这样定义基础结构:
    ```golang
    type Data struct {
    Type string `json:"type"`
    Body json.RawMessage `json:"type"`
    }
    ```

    这样的话你就可以先解析出 Type ,Body 还是 json 串,然后再根据 Type 将 Body 解析到对应的结构体
    masterclock
        14
    masterclock  
       2022-01-15 23:23:03 +08:00
    不转,用 gjson 这样的东西先取出可以识别的字段,然后根据场景:
    1. 转为对应的 struct
    2. 还是不转,直接变类型为某个 interface
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3491 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 11:03 · PVG 19:03 · LAX 04:03 · JFK 07:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.