Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to judge zero value of golang reflect

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?

like image 457
up duan Avatar asked Mar 11 '16 02:03

up duan


People also ask

How do you know if reflection is nil?

The reflect. IsNil() Function in Golang is used to check whether its argument v is nil. The argument must be a chan, func, interface, map, pointer, or slice value; if it is not, IsNil panics.

What is reflect value Golang?

The reflect. ValueOf() Function in Golang is used to get the new Value initialized to the concrete value stored in the interface i. To access this function, one needs to imports the reflect package in the program.

Does Golang have reflection?

Reflection is the ability of a program to introspect and analyze its structure during run-time. In Go language, reflection is primarily carried out with types. The reflect package offers all the required APIs/Methods for this purpose.

How does reflect work Golang?

Reflection acts on three important reflection properties that every Golang object has: Type, Kind, and Value. 'Kind' can be one of struct, int, string, slice, map, or one of the other Golang primitives. The reflect package also allows you to modify the value of a specific field given the reflected value of a field.


1 Answers

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 && 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("NULL")
    } else {
        if val.CanInterface() {
            fmt.Printf("if is %#+v (%v)\n", val.Interface(), val.Interface() == nil)
        }
    }
    fmt.Println(v.(*string) == nil)
}

playground

like image 64
OneOfOne Avatar answered Nov 26 '22 02:11

OneOfOne