【问题标题】:How can I use reflect.Value.Call() with a nil input?如何将 reflect.Value.Call() 与 nil 输入一起使用?
【发布时间】:2014-09-06 13:11:02
【问题描述】:

我想在 Go 中调用一个函数,在方法值上使用 reflect.Value.Call,并将 nil 作为参数传递。请参阅下面的代码以获取说明。

我尝试在输入数组中使用reflect.ValueOf(nil)reflect.Value{},但第一次出现恐慌,因为 nil 没有价值;当我将它传递给 Call 时,第二个恐慌,因为它是零 reflect.Value。

请注意,正如代码所示,当然可以将 nil 传递给函数而不进行反射,包括当该参数是接收者时。 问题是:是否可以使用 reflect.Value.Call 调用 func,将其中一个参数作为 nil 传递?

您可以在以下位置构建和运行以下代码: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()
}

【问题讨论】:

    标签: reflection go


    【解决方案1】:

    一种选择是简单地告诉reflect,您的意思是指向Thing 的零指针:

    func reflectCallNonNil() {
        m, _ := typ.MethodByName("DoSomething")
        f := m.Func
        f.Call([]reflect.Value{reflect.ValueOf((*Thing)(nil))})
    
    }
    

    此外,您可以使用reflect.Zero,它为您提供类型的“零值”。所以这里的 nil 是指向Thing 的指针的零值。

    因此,这样做会起作用:

    func reflectCallNil() {
        m, _ := typ.MethodByName("DoSomething")
        f := m.Func
        f.Call([]reflect.Value{reflect.Zero(reflect.TypeOf(&Thing{}))})
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 2018-08-30
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      相关资源
      最近更新 更多