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
?
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With