Go 判断指针变量未初始化或值 = nil

947 阅读1分钟

前言

在很多初学者使用 Go 的时候,都会常使用 data == nil 来判断,但是这并不是万能的,如果是一个指针结构体的话,就无法判断成功

案例演示

实际项目中是有可能会出现,比如说多个函数 return 出来的

package main

import (
   "encoding/json"
   "log"
   "testing"
)

type Data struct {
   Mobile string `json:"mobile"`
}

type Success struct {
   Code int64  `json:"code"`
   Msg  string `json:"msg"`
   Data any    `json:"data,omitempty"`// 1.18 才有的,等同于 interface{}
}

func TestResp(t *testing.T) {
   var data *Data
   s := &Success{
      Data: data,
   }
   b, _ := json.Marshal(s)
   log.Println(string(b))
}

以上代码将会输出

2022/03/16 10:51:27 {"code":0,"msg":"","data":null}

在这里我们可以发现,当结构体指针变量并未初始化时,即使我们指定了 datajson tag = omitempty,最终还是会输出 null,这是为什么呢?感兴趣的朋友可以追踪下 json.Marshal 方法

解决方案

v := reflect.ValueOf(data)
if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) {
    data = nil
}

结尾

最终,这样就可以实现指针变量未初始化以及 nil 忽略字段