如何判断 golang reflect 的零值?

huangapple go评论93阅读模式
英文:

How to judge zero value of golang reflect

问题

这个程序的输出是:

...
panic: reflect: 在零值上调用 reflect.Value.CanInterface

goroutine 1 [running]:
panic(0xd65a0, 0xc82005e000)
    /usr/local/go/src/runtime/panic.go:464 +0x3e6
reflect.Value.CanInterface(0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/reflect/value.go:897 +0x62
...

出了什么问题?为什么 v == nil 的结果是 false

英文:
package main

import (
	"fmt"
	"reflect"
)

func main() {
	var p1 *string = nil
	var v interface{} = p1
	val := reflect.Indirect(reflect.ValueOf(v))
	if v == nil {
		fmt.Printf("NULL")
	} else {
		if val.CanInterface() {
			fmt.Printf("if is %v\n", val.Interface())
		}
	}
}

This program's output is:

···

panic: reflect: call of reflect.Value.CanInterface on zero Value

goroutine 1 [running]:
panic(0xd65a0, 0xc82005e000)
	/usr/local/go/src/runtime/panic.go:464 +0x3e6
reflect.Value.CanInterface(0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/reflect/value.go:897 +0x62

···

What's the matter? Why if v == nil is false?

答案1

得分: 16

v 不是空值,它包含一个 *string

然而,如果你想检查反射值是否有效(非零),你可以使用 val.IsValid() 进行检查。

另外,如果你想检查它是否为空,你可以检查 if val.Kind() == reflect.Ptr && val.IsNil() {}

这是一个小示例:

func main() {
    var p1 *string = nil
    var v interface{} = p1
    // 这将返回一个无效值,因为它将返回一个空指针的 Elem。
    //val := reflect.Indirect(reflect.ValueOf(v))
    val := reflect.ValueOf(v) // 注释掉这行以查看差异。
    if !val.IsValid() {
        fmt.Printf("NULL")
    } else {
        if val.CanInterface() {
            fmt.Printf("if is %#+v (%v)\n", val.Interface(), val.Interface() == nil)
        }
    }
    fmt.Println(v.(*string) == nil)
}

<kbd>playground</kbd>

英文:

v isn't nil, it contains a *string.

However, if you want to check if a reflect value is valid (non-zero), you can use val.IsValid() to check.

Also if you want to check if it's nil, you can check if val.Kind() == reflect.Ptr &amp;&amp; val.IsNil() {}.

A little demo:

func main() {
	var p1 *string = nil
	var v interface{} = p1
	// this will return an invalid value because it will return the Elem of a nil pointer.
	//val := reflect.Indirect(reflect.ValueOf(v))
	val := reflect.ValueOf(v) // comment this to see the difference.
	if !val.IsValid() {
		fmt.Printf(&quot;NULL&quot;)
	} else {
		if val.CanInterface() {
			fmt.Printf(&quot;if is %#+v (%v)\n&quot;, val.Interface(), val.Interface() == nil)
		}
	}
	fmt.Println(v.(*string) == nil)
}

<kbd>playground</kbd>

huangapple
  • 本文由 发表于 2016年3月11日 10:38:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/35931264.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定