You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go语言中检查泛型类型是否为nil?

泛型函数中安全检查参数是否为nil的实现方式

你的示例代码之所以触发panic,是因为reflect.Value.IsNil()方法只能用于指针、通道、函数、接口、map、切片这些可被赋值为nil的类型。当传入像int这样的值类型时,调用IsNil()会直接引发panic——值类型本身不存在nil的状态,也不支持这个方法。

下面是两种最佳实现方案,根据你的需求选择:

方案1:支持所有类型,仅对可nil类型做检查

如果你的函数需要接受任意类型,只对那些能为nil的类型做nil校验,可以先通过反射判断类型是否支持IsNil(),再执行检查:

package main

import (
	"fmt"
	"reflect"
)

func main() {
	Hello(1)          // 正常输出:Hello 1
	Hello((*int)(nil))// 触发panic:id cannot be nil
	Hello([]int(nil)) // 触发panic:id cannot be nil
}

func Hello[T any](id T) {
	v := reflect.ValueOf(id)
	// 仅对可nil的类型执行检查
	switch v.Kind() {
	case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Slice:
		if v.IsNil() {
			panic("id cannot be nil")
		}
	// 值类型无需检查,直接跳过
	default:
	}
	fmt.Printf("Hello %v\n", id)
}

方案2:编译期限制仅接受可nil类型

如果你的函数只允许接收可nil的类型(比如指针、切片、map等),可以通过类型约束在编译阶段就拦截非法类型,同时直接用== nil判断,无需反射:

package main

import "fmt"

// 定义可nil类型的约束
type Nilable interface {
	~*any | ~[]any | ~map[any]any | ~chan any | ~func() | error
}

func main() {
	// Hello(1) // 编译报错:int does not implement Nilable
	Hello((*int)(nil))// 触发panic:id cannot be nil
	Hello([]int{1,2}) // 正常输出:Hello [1 2]
}

func Hello[T Nilable](id T) {
	if id == nil {
		panic("id cannot be nil")
	}
	fmt.Printf("Hello %v\n", id)
}

方案对比

  • 方案1更灵活,支持任意类型,但依赖反射,性能略低
  • 方案2更安全,编译期就能排查非法类型,无需反射,性能更好

内容的提问来源于stack exchange,提问作者Ado Ren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 09:35:15