• Golang结构体序列化与反序列化时默认值的问题


    package scripts_stroage
    
    import (
        "encoding/json"
        "fmt"
        "testing"
    )
    
    // 反序列化时,如果不传对应 json里面的字段,就会解析为 对应数据类型的 "零值"
    type TestStruct1 struct {
        Name  string `json:"name"`
        Age   int    `json:"age"`
        IsBoy bool   `json:"is_boy"`
    }
    
    // 类型是指针类型
    // 序列化时,如果不指定value,就会被解析成 null(json的空值)
    //反序列化时,如果不传对应 json里面的字段,就会解析为 nil
    type TestStruct2 struct {
        Name  *string `json:"name"`
        Age   *int    `json:"age"`
        IsBoy *bool   `json:"is_boy"`
    }
    
    func TestST1(t *testing.T) {
    
        // -------------- 序列化测试 ----------------
        // 1、序列化成一个字符串,有默认值
        t1 := TestStruct1{}
        data1, _ := json.Marshal(t1)
        fmt.Printf("data1: %s \n", data1) // {"name":"","age":0,"is_boy":false}
    
        // 2、序列化成一个字符串,默认都序列化成了 null !!!
        t2 := TestStruct2{}
        data2, _ := json.Marshal(t2)
        fmt.Printf("data2: %s \n", data2) // data2: {"name":null,"age":null,"is_boy":null}
    
        // -------------- 反序列化测试 ----------------
        fmt.Println("===================================================")
        s := `{"gender":"male"}` // 没有json指定的字段~
        // 用第一个反序列化 返回:字符串、数字、bool值 的默认值
        var sObj1 TestStruct1
        _ = json.Unmarshal([]byte(s), &sObj1)
        fmt.Println("sRet1: ", sObj1.Name, sObj1.Age, sObj1.IsBoy) // sRet1:   0 false
    
        // TODO 用第二个反序列化 返回:三个nil!!!因为我们是用指针去反序列化的,指针的默认值就是nil
        var sObj2 TestStruct2
        _ = json.Unmarshal([]byte(s), &sObj2)
        fmt.Println("sRet2: ", sObj2.Name, sObj2.Age, sObj2.IsBoy) // sRet2:  <nil> <nil> <nil>
    
        // TODO 第二种方法反序列化出来以后,再次赋值,注意只能用变量去设置,因为我们可以取到变量的地址,但是不能获取常量的地址
        defaultName := "whw"
        defaultAge := 22
        defaultBoy := true
        if sObj2.Name == nil {
            sObj2.Name = &defaultName
        }
        if sObj2.Age == nil {
            sObj2.Age = &defaultAge
        }
        if sObj2.IsBoy == nil {
            sObj2.IsBoy = &defaultBoy
        }
        // TODO 因为是指针,所以用 * 去取value
        fmt.Println("sRet2再次初始化: ", *sObj2.Name, *sObj2.Age, *sObj2.IsBoy) // sRet2再次初始化:  whw 22 true
    
    }

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    序列化结果不想带一些属性的零值—>加omitempty标签

    写一个方法去返回 *bool 解析后的值并根据业务需求设置默认值

    ~~~~~~~~~~~~~~~~~~

  • 相关阅读:
    练习二十七:递归函数应用
    mysql8.0数据库忘记密码时进行修改方法
    格式化字符串两种方式
    练习二十六:阶乘计算(递归)
    练习二十五:阶乘之和计算
    Dapper批量添加
    c# FTP操作类(转)
    c# 依赖注入之---反射(转)
    c# 依赖注入之---setterInjection(转)
    php遍历数组赋值
  • 原文地址:https://www.cnblogs.com/paulwhw/p/15676015.html
Copyright © 2020-2023  润新知