如何使用Golang的反射实例化nil错误?

时间:2018-06-28 23:19:49

标签: go reflection

我正在使用reflect.MakeFunc编写一个函数。该函数可以返回错误。成功时,我希望它为错误类型的返回值返回nil。我该如何使用反射?目前我有这个:

package main

import (
    "fmt"
    "reflect"
    "errors"        
)

func main() {
    fmt.Println("Hello, playground")
    f := func() error {return nil}
    fn := reflect.MakeFunc(reflect.TypeOf(f), func(args []reflect.Value) []reflect.Value {
        return []reflect.Value{reflect.New(reflect.TypeOf(errors.New("")))}
    }).Interface().(func() error)
    fmt.Printf("err: %v", fn())
}

我得到panic: reflect: function created by MakeFunc using closure returned wrong type: have **errors.errorString for error。我还尝试在.Elem()之后添加reflect.New(reflect.TypeOf(errors.New(""))),但得到panic: reflect: function created by MakeFunc using closure returned wrong type: have *errors.errorString for error。我尝试了.Elem().Elem(),但遇到了细分错误。

如何获取代表nil错误的reflect.Value?

2 个答案:

答案 0 :(得分:0)

我找到了一种方法-reflect.ValueOf(f).Call(nil)。也许有更好的选择。

答案 1 :(得分:0)

使用以下内容:

var nilError = reflect.Zero(reflect.TypeOf((*error)(nil)).Elem())

func main() {
    fmt.Println("Hello, playground")
    f := func() error { return nil }
    fn := reflect.MakeFunc(reflect.TypeOf(f), func(args []reflect.Value) []reflect.Value {
        return []reflect.Value{nilError}
    }).Interface().(func() error)
    fmt.Printf("err: %v", fn())
}

让我们分解一下。第一步是为reflect.Typeerror获得一个reflect.TypeOf((*error)(nil)).Elem()。更简单的reflect.TypeOf((error)(nil))不起作用,因为参数的具体值为nilnil没有类型,而且也不是我们想要的类型。解决方法是将指针传递到error,然后在类型上调用Elem(),以获取relfect.Type的{​​{1}}。

第二步是为类型创建一个零值。