如何判断 golang reflect 的零值?

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

How to judge zero value of golang reflect

问题

这个程序的输出是:

  1. ...
  2. panic: reflect: 在零值上调用 reflect.Value.CanInterface
  3. goroutine 1 [running]:
  4. panic(0xd65a0, 0xc82005e000)
  5. /usr/local/go/src/runtime/panic.go:464 +0x3e6
  6. reflect.Value.CanInterface(0x0, 0x0, 0x0, 0x0)
  7. /usr/local/go/src/reflect/value.go:897 +0x62
  8. ...

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

英文:
  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. func main() {
  7. var p1 *string = nil
  8. var v interface{} = p1
  9. val := reflect.Indirect(reflect.ValueOf(v))
  10. if v == nil {
  11. fmt.Printf("NULL")
  12. } else {
  13. if val.CanInterface() {
  14. fmt.Printf("if is %v\n", val.Interface())
  15. }
  16. }
  17. }

This program's output is:

  1. ···
  2. panic: reflect: call of reflect.Value.CanInterface on zero Value
  3. goroutine 1 [running]:
  4. panic(0xd65a0, 0xc82005e000)
  5. /usr/local/go/src/runtime/panic.go:464 +0x3e6
  6. reflect.Value.CanInterface(0x0, 0x0, 0x0, 0x0)
  7. /usr/local/go/src/reflect/value.go:897 +0x62
  8. ···

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

答案1

得分: 16

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

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

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

这是一个小示例:

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

<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:

  1. func main() {
  2. var p1 *string = nil
  3. var v interface{} = p1
  4. // this will return an invalid value because it will return the Elem of a nil pointer.
  5. //val := reflect.Indirect(reflect.ValueOf(v))
  6. val := reflect.ValueOf(v) // comment this to see the difference.
  7. if !val.IsValid() {
  8. fmt.Printf(&quot;NULL&quot;)
  9. } else {
  10. if val.CanInterface() {
  11. fmt.Printf(&quot;if is %#+v (%v)\n&quot;, val.Interface(), val.Interface() == nil)
  12. }
  13. }
  14. fmt.Println(v.(*string) == nil)
  15. }

<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:

确定