简体   繁体   中英

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

I am writing a function using reflect.MakeFunc. That function can return an error. When it succeeds, I want it to return nil for its error-typed return value. 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 . 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 . I tried .Elem().Elem() , and I got a segmentation fault.

How can I get a reflect.Value representing a nil error?

I found one way - 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() . The simpler reflect.TypeOf((error)(nil)) does not work because the concrete value of the argument is nil . There's no type for nil and it's not the type we want anyway. The workaround is to pass a pointer to error and then call Elem() on the type to get the relfect.Type for error .

The second step is to create a zero value for the type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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