I want to invoke a function in Go, using reflect.Value.Call on a method value, and pass nil as a parameter. See the code below for an illustration.
I have tried using reflect.ValueOf(nil)
and reflect.Value{}
in the input array, but the first panics because nil has no value; the second panics when I pass it to Call, because it is a Zero reflect.Value.
Note that, as the code illustrates, it is certainly possible to pass nil to a function without reflection, including when that argument is the receiver. The question is: Is it possible to invoke a func using reflect.Value.Call, passing one of those parameters as nil?
You can build and run the code below at: 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()
}
One option is to simply tell 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))})
}
Also, you can use reflect.Zero
which gives you a "zero value" for a type. So nil in this context is the zero value of pointer to Thing
.
Thus, doing this will work:
func reflectCallNil() {
m, _ := typ.MethodByName("DoSomething")
f := m.Func
f.Call([]reflect.Value{reflect.Zero(reflect.TypeOf(&Thing{}))})
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.