How can I use reflect.Value.Call () with null input?
I want to call a function in Go using reflection.Value.Call on a method value and pass nil as a parameter. See the code below for an illustration.
I tried to use reflect.ValueOf(nil)
it reflect.Value{}
in the input array too, but first panics because nil doesn't matter; second panic when I pass it to Call because it is Zero reflect.Value.
Note that, as the code shows, it is certainly possible to pass nil to a function without reflection, even when this argument is the receiver. Question: is it possible to call the function func using the reflection function .Value.Call passing one of these parameters as nil?
You can build and run the code below: http://play.golang.org/p/x9NXMDHWdM
package main
import "reflect"
type Thing struct{}
var (
thingPointer = &Thing{}
typ = reflect.TypeOf(thingPointer)
)
func (t *Thing) DoSomething() {
if t == nil {
println("t was nil")
} else {
println("t was not nil")
}
}
func normalInvokation() {
thingPointer.DoSomething()
// prints "t was not nil"
t := thingPointer
t = nil
t.DoSomething()
// prints "t was nil"
}
func reflectCallNonNil() {
m, _ := typ.MethodByName("DoSomething")
f := m.Func
f.Call([]reflect.Value{reflect.ValueOf(&Thing{})})
// prints "t was not nil"
}
func reflectCallNil() {
// m, _ := typ.MethodByName("DoSomething")
// f := m.Func
// f.Call(???)
// how can I use f.Call to print "t was nil" ?
}
func main() {
normalInvokation()
reflectCallNonNil()
reflectCallNil()
}
source to share
One option is to simply say reflect
that you mean a nil pointer to Thing
:
func reflectCallNonNil() {
m, _ := typ.MethodByName("DoSomething")
f := m.Func
f.Call([]reflect.Value{reflect.ValueOf((*Thing)(nil))})
}
Alternatively, you can use reflect.Zero
that gives you a "null value" for the type. Thus nil in this context is the null value of a pointer to Thing
.
So doing this will work:
func reflectCallNil() {
m, _ := typ.MethodByName("DoSomething")
f := m.Func
f.Call([]reflect.Value{reflect.Zero(reflect.TypeOf(&Thing{}))})
}
source to share