Golang中如何检测指针引用的结构体是否为nil
Golang中如何检测指针引用的结构体是否为nil
import (
"fmt"
)
type str struct {
a string
}
func main() {
var p *str
chk(p)
}
func chk(s interface{}) {
fmt.Println("Check", s) // 这里打印的是nil
if s == nil { // 但这里无法检查
fmt.Println("It is null....")
}
fmt.Println("Hello, playground")
}
8 回复
这是我遇到的错误…我尝试了各种类型的值
更多关于Golang中如何检测指针引用的结构体是否为nil的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
感谢Lutzhorn,
你的回复非常有用
还有一件事
如何仅检查值是否为空?
int 和 string 不能这样使用。但你为什么要将它们作为 interface{} 传递?你想要实现什么功能?
panic: reflect: call of reflect.Value.IsNil on string Value
goroutine 1 [running]:
reflect.Value.IsNil(0xee6e0, 0x195920, 0x98, 0x195920, 0x98, 0xf0740)
/usr/local/go/src/reflect/value.go:1018 +0x160
main.chk(0xee6e0, 0x195920)
/tmp/sandbox753849162/main.go:33 +0xc0
main.main()
/tmp/sandbox753849162/main.go:21 +0x60
import (
"fmt"
"reflect"
)
var string1 string
var int1 int
type strtemp struct {
newstr string
}
type str struct {
a string
st *strtemp
}
func main() {
var p *str
chk(string1)
chk(int1)
chk(p)
}
func chk(s interface{}) {
fmt.Printf("value=%v type=%t\n", s, s)
// s的类型不是nil,所以以下条件为假
if s == nil {
fmt.Println("s is nil....")
}
// s的值为nil,以下条件为真
if reflect.ValueOf(s).IsNil() {
fmt.Println("value of s is nil")
}
fmt.Println("Hello, playground")
}
看看这个:
package main
import (
"fmt"
)
type str struct {
a string
}
func main() {
var p *str
chk(p)
}
func chk(s interface{}) {
fmt.Printf("value=%v type=%t\n", s, s)
// s的类型不为nil,因此以下判断为false
if s == nil {
fmt.Println("It is null....")
}
fmt.Println("Hello, playground")
}
输出结果为
value=<nil> type=%!t(*main.str=<nil>)
Hello, playground
要成为nil,类型和值都必须为nil。
另请参阅 https://u.lhorn.de/mo3Z。
尝试这个:
package main
import (
"fmt"
"reflect"
)
type str struct {
a string
}
func main() {
var p *str
chk(p)
}
func chk(s interface{}) {
fmt.Printf("value=%v type=%t\n", s, s)
// s的类型不是nil,所以以下条件为false
if s == nil {
fmt.Println("s is nil....")
}
// s的值为nil,以下条件为true
if reflect.ValueOf(s).IsNil() {
fmt.Println("value of s is nil")
}
fmt.Println("Hello, playground")
}
输出:
value=<nil> type=%!t(*main.str=<nil>)
value of s is nil
Hello, playground
另请参阅 https://u.lhorn.de/m65w。
在Go语言中,当接口值包含一个具体的类型但值为nil时(比如*str类型的nil指针),直接与nil比较会返回false。这是因为接口值由类型和值两部分组成,虽然值为nil,但类型信息仍然存在。
以下是几种正确的检测方法:
方法1:使用反射包(reflect)
import (
"fmt"
"reflect"
)
type str struct {
a string
}
func main() {
var p *str
chk(p)
}
func chk(s interface{}) {
if s == nil {
fmt.Println("It is nil")
return
}
// 使用反射检查底层值是否为nil
v := reflect.ValueOf(s)
if v.Kind() == reflect.Ptr && v.IsNil() {
fmt.Println("Pointer to struct is nil")
return
}
fmt.Println("Not nil")
}
方法2:类型断言检查
func chk(s interface{}) {
if s == nil {
fmt.Println("It is nil")
return
}
// 类型断言检查
switch v := s.(type) {
case *str:
if v == nil {
fmt.Println("*str is nil")
return
}
default:
fmt.Printf("Unknown type: %T\n", v)
}
fmt.Println("Not nil")
}
方法3:针对特定类型的检查函数
func chk(s interface{}) {
if isNil(s) {
fmt.Println("It is nil")
return
}
fmt.Println("Not nil")
}
func isNil(i interface{}) bool {
if i == nil {
return true
}
switch v := i.(type) {
case *str:
return v == nil
// 可以添加更多类型的检查
default:
return false
}
}
方法4:直接传递指针(推荐)
func main() {
var p *str
chkPtr(p)
}
func chkPtr(s *str) {
if s == nil {
fmt.Println("Pointer is nil")
return
}
fmt.Println("Pointer is not nil")
}
运行这些代码,当传入*str类型的nil指针时,会正确检测到nil状态。方法4是最简洁和高效的解决方案,因为它避免了接口包装的开销。

