首页 > 解决方案 > 如何使用 Golang 的反射实例化 nil 错误?

问题描述

我正在使用 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()after reflect.New(reflect.TypeOf(errors.New(""))),但我得到了panic: reflect: function created by MakeFunc using closure returned wrong type: have *errors.errorString for error. 我试过.Elem().Elem()了,我遇到了分段错误。

如何获得表示零错误的 reflect.Value?

标签: goreflection

解决方案


使用以下内容:

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.Typefor error: reflect.TypeOf((*error)(nil)).Elem()。更简单reflect.TypeOf((error)(nil))的方法不起作用,因为参数的具体值是nil。没有类型 fornil也不是我们想要的类型。解决方法是传递一个指针error,然后调用Elem()类型来获取relfect.Typefor error

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


推荐阅读