Go 优雅判断 interface 是否为 nil

问题

问题就在于下面这句话,文章也是有列出的:

即使接口持有的值为 nil,也不意味着接口本身为 nil。

但是在执行以下语句的时候,是有可能报 panic 的:

go 复制代码
return reflect.ValueOf(x).IsNil()

而输出也是非常明显的指出错误:

go 复制代码
panic: reflect: call of reflect.Value.IsNil on int Value

因为不可 nil 的 interface 是不能使用 reflect.Value.IsNil 方法。

那么问题就很好解决了。

解决方式

我们在执行 reflect.Value.IsNil 方法之前,进行一次判断是否为指针即可:

go 复制代码
func IsNil(x interface{}) bool {
	if x == nil {
		return true
	}
	rv := reflect.ValueOf(x)
	return rv.Kind() == reflect.Ptr && rv.IsNil()
}

重点在于 rv.Kind() == reflect.Ptr && rv.IsNil() 这段代码。

这段代码的作用:

判断 x 的类型是否为指针。

判断 x 的值是否真的为 nil。

下面我们使用几种常见的数据类型来进行测试:

go 复制代码
func IsNil(x interface{}) bool {
	if x == nil {
		return true
	}
	rv := reflect.ValueOf(x)
	return rv.Kind() == reflect.Ptr && rv.IsNil()
}

func main() {
	fmt.Printf("int IsNil: %t\n", IsNil(returnInt()))
	fmt.Printf("intPtr IsNil: %t\n", IsNil(returnIntPtr()))
	fmt.Printf("slice IsNil: %t\n", IsNil(returnSlice()))
	fmt.Printf("map IsNil: %t\n", IsNil(returnMap()))
	fmt.Printf("interface IsNil: %t\n", IsNil(returnInterface()))
	fmt.Printf("structPtr IsNil: %t\n", IsNil(returnStructPtr()))
}

func returnInt() interface{} {
	var value int
	return value
}

func returnIntPtr() interface{} {
	var value *int
	return value
}

func returnSlice() interface{} {
	var value []string
	return value
}

func returnMap() interface{} {
	var value map[string]struct{}
	return value
}

func returnInterface() interface{} {
	var value interface{}
	return value
}

type People struct {
	Name string
}

func returnStructPtr() interface{} {
	var value *People
	return value
}

我们先后使用了 int、*int、slice、map、interface{}、自定义结构体 来测试此 IsNil 方法。运行程序输出为:

go 复制代码
int IsNil: false
intPtr IsNil: true
slice IsNil: false
map IsNil: false
interface IsNil: true
structPtr IsNil: true

从测试结果来看,目前是符合我们对此方法的定位的。

相关推荐
znsoft4 小时前
MaClaw(码卡龙)技术拆解:一个 Go + React 的可自进化智能体平台
开发语言·react.js·golang
茶底世界之下8 小时前
雨夜街角裁成方图,人物与冷暖光还能共存吗?
ios
youdexiang10 小时前
IOS录音APP拍照记录能和音频同步吗
ios·音视频
2501_9159090611 小时前
Windows 打开 Xcode 工程,编译调试 Xcode 项目并和 Mac 同事协作
ide·windows·vscode·macos·ios·个人开发·xcode
互联网江湖11 小时前
iPhone Duo跌倒,国产折叠屏手机吃饱?
ios·智能手机·iphone
念何架构之路11 小时前
Go 标准库 database/sql 详解
数据库·sql·golang
modelmd12 小时前
Go 切片、映射常见使用场景
开发语言·后端·golang
超级架构师1 天前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
zwd20051 天前
词频是什么?生词滑块 zipf 3.0 到 5.0 怎么调:同一屏从 0 个生词到 11 个
ios·iphone·效率工具·英语学习·词频·屏幕翻译
我就是全世界1 天前
OpenCode Go 套餐划算吗:先看你用哪个模型
开发语言·后端·golang