我正在使用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(),但出现了细分错误。
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?
使用以下内容:
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.Type为error: reflect.TypeOf((*error)(nil)).Elem()。更简单的方法reflect.TypeOf((error)(nil))不起作用,因为参数的具体值为nil。没有类型,nil也不是我们想要的类型。解决方法是传递一个指针error,然后调用Elem()该类型以获取relfect.Typefor error。
reflect.Type
error
reflect.TypeOf((*error)(nil)).Elem()
reflect.TypeOf((error)(nil))
nil
Elem()
relfect.Type
第二步是为类型创建一个零值。