Go json反序列化“null“结果为nil踩坑

Go json反序列化"null"结果为nil踩坑

先说结论,“null"是json的一个关键字,json序列化时,会把nil【即指针类型(比如slice、map和*T)的未初始化时的形态】序列化为字符串"null”,反序列化时会把字符串"null",如果目标类型是指针类型,则会反序列化为nil,但是目标结构体内部的自定义type的指针类型不会成为nil【见测试代码图二的mal的E字段,但这就有点不懂为啥了…】

建议对"null"进行一下特殊处理

测试代码

需要注意的是fmt很多时候打印nil的指针类型时不会输出nil,比如nil的slice和map,会打印成[]和map[];

package main

import (
   "fmt"
   jsoniter "github.com/json-iterator/go"
)

type Marshaler struct {
   A map[string]interface{}
   B []string
   C [10]int
   D *string
   E *EE
   F string
   g string
}
type EE struct {
   EEE []string
}

func main() {
   mal := Marshaler{
      E: &EE{},
   }
   mal1 := &Marshaler{}
   e1 := &EE{}
   e2 := EE{EEE: []string{}}
   var t1 *string
   var t2 []int
   var t3 map[string]interface{}
   var t4 = make([]string, 0)
   res1, _ := jsoniter.MarshalToString(mal)
   res2, _ := jsoniter.MarshalToString(mal1)
   res3, _ := jsoniter.MarshalToString(e1)
   res4, _ := jsoniter.MarshalToString(e2)
   res5, _ := jsoniter.MarshalToString(t1)
   res6, _ := jsoniter.MarshalToString(t2)
   res7, _ := jsoniter.MarshalToString(t3)
   res8, _ := jsoniter.MarshalToString(t4)
   fmt.Printf("res1: %+v\n", res1)
   fmt.Printf("res2: %+v\n", res2)
   fmt.Printf("res3: %+v\n", res3)
   fmt.Printf("res4: %+v\n", res4)
   fmt.Printf("res5: %+v\n", res5)
   fmt.Printf("res6: %+v\n", res6)
   fmt.Printf("res7: %+v\n", res7)
   fmt.Printf("res8: %+v\n", res8)

   params := make(map[string]interface{})
   if err := jsoniter.Unmarshal([]byte(res6), &params); err != nil {
      fmt.Println("null Unmarshal err:", err)
   } else {
      fmt.Printf("null Unmarshal map:  %+v\n", params)
   }

   if err := jsoniter.Unmarshal([]byte(res6), &mal); err != nil {
      fmt.Println("null Unmarshal err:", err)
   } else {
      fmt.Printf("null Unmarshal Marshaler: %+v\n", mal)
   }

   if err := jsoniter.Unmarshal([]byte(res6), &mal1); err != nil {
      fmt.Println("null Unmarshal err:", err)
   } else {
      fmt.Printf("null Unmarshal Marshaler: %+v\n", mal1)
   }

   if err := jsoniter.Unmarshal([]byte(res6), &t4); err != nil {
      fmt.Println("null Unmarshal err:", err)
   } else {
      fmt.Printf("null Unmarshal []string: %+v\n", t4)
      fmt.Println(t4 == nil)
   }
}
输出:
res1: {"A":null,"B":null,"C":[0,0,0,0,0,0,0,0,0,0],"D":null,"E":{"EEE":null},"F"
:""}
res2: {"A":null,"B":null,"C":[0,0,0,0,0,0,0,0,0,0],"D":null,"E":null,"F":""}    
res3: {"EEE":null}
res4: {"EEE":[]}
res5: null
res6: null
res7: null
res8: []
//下面的打印不够准确,看debug截图
null Unmarshal map:  map[]
null Unmarshal Marshaler: {A:map[] B:[] C:[0 0 0 0 0 0 0 0 0 0] D:<nil> E:0xc000
004510 F: g:}
null Unmarshal Marshaler: <nil>
null Unmarshal []string: []
tru
debug截图

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值