简体   繁体   English

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

[英]How can I instantiate a nil error using Golang's reflect?

I am writing a function using reflect.MakeFunc. 我正在使用reflect.MakeFunc编写函数。 That function can return an error. 该函数可以返回错误。 When it succeeds, I want it to return nil for its error-typed return value. 成功时,我希望它为错误类型的返回值返回nil。 How can I do that using reflect? 我该如何使用反射? Currently I have this: 目前我有这个:

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

I get panic: reflect: function created by MakeFunc using closure returned wrong type: have **errors.errorString for error . 我感到panic: reflect: function created by MakeFunc using closure returned wrong type: have **errors.errorString for error I also tried adding a .Elem() after reflect.New(reflect.TypeOf(errors.New(""))) , but I got panic: reflect: function created by MakeFunc using closure returned wrong type: have *errors.errorString for error . 我也试过在reflect.New(reflect.TypeOf(errors.New(""))) .Elem()之后添加一个.Elem() ,但我感到panic: reflect: function created by MakeFunc using closure returned wrong type: have *errors.errorString for error I tried .Elem().Elem() , and I got a segmentation fault. 我尝试了.Elem().Elem() ,但出现了段错误。

How can I get a reflect.Value representing a nil error? 如何获得表示nil错误的reflect.Value?

I found one way - reflect.ValueOf(f).Call(nil) . 我找到了一种方法reflect.ValueOf(f).Call(nil) Maybe there's a better one. 也许有更好的选择。

Use the following: 使用以下内容:

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

Let's break this down. 让我们分解一下。 The first step is to get a reflect.Type for error : reflect.TypeOf((*error)(nil)).Elem() . 第一步是获取errorreflect.Typereflect.TypeOf((*error)(nil)).Elem() The simpler reflect.TypeOf((error)(nil)) does not work because the concrete value of the argument is nil . 更简单的reflect.TypeOf((error)(nil))不起作用,因为参数的具体值为nil There's no type for nil and it's not the type we want anyway. 没有nil的类型,这也不是我们想要的类型。 The workaround is to pass a pointer to error and then call Elem() on the type to get the relfect.Type for error . 解决方法是传递一个指向error的指针,然后对该类型调用Elem()以获取errorrelfect.Type

The second step is to create a zero value for the type. 第二步是为类型创建一个零值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM