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()
}

      

+3


source to share


1 answer


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{}))})
}

      

+6


source







All Articles