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

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

先说结论,“null"是json的一个关键字,jsoniter这个库【其他库没测】在进行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
", res1)
   fmt.Printf("res2: %+v
", res2)
   fmt.Printf("res3: %+v
", res3)
   fmt.Printf("res4: %+v
", res4)
   fmt.Printf("res5: %+v
", res5)
   fmt.Printf("res6: %+v
", res6)
   fmt.Printf("res7: %+v
", res7)
   fmt.Printf("res8: %+v
", 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
", params)
   }

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

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

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

输出:

debug截图

经验分享 程序员 微信小程序 职场和发展