去反思。如何检查reflect.Type是否为错误类型?

时间:2015-06-06 23:16:44

标签: reflection go metaprogramming

我需要确定检查一下reflect.Type是一个错误。

没有反映错误的类型。 go反射中检查类型错误的正式/惯用方式是什么?

Go Playground Full Example

//return map of default values, based on each return type of a function
// error  => err=nil
// bool   => true
// struct => new struct
func getDefaultValue(originalFunction interface{}) map[int]reflect.Value {
    defaultValues := make(map[int]reflect.Value)

    typeOfFunc := reflect.ValueOf(originalFunction).Type()

    numOut := typeOfFunc.NumOut() //number of function returns

    for i := 0; i < numOut; i++ {

        typeOut := typeOfFunc.Out(i) // type of return for index i
        switch typeOut.Kind() {

        case reflect.Bool:
            defaultValues[i] = reflect.ValueOf(true)

        case reflect.Struct:
            defaultValues[i] = reflect.New(typeOut()).Elem()

        // --> How to identify reflect.Type error assuredly, using switch or if...
        //case reflect.error: //don't exists
        //  var err error = nil
        //  defaultValues[i] = reflect.ValueOf(&err).Elem()

        default:
            //var err error = nil
            //defaultValues[i] = reflect.ValueOf(&err).Elem()
            fmt.Println("type of return index ", i, " was not identified")

        }

        fmt.Println("type of return index ", i, typeOut, "kind", typeOut.Kind(), "assign to err ", typeOut.AssignableTo(reflect.TypeOf(errors.New(""))))
    }

    return defaultValues
}

3 个答案:

答案 0 :(得分:9)

在Go error中并不特别。 error只是一个预先声明的接口类型,因此它没有自己的Kind in reflect。 尝试一下:

errorInterface  := reflect.TypeOf((*error)(nil)).Elem()
...
case reflect.Interface:
    if typOute.Implements(errorInterface)  // it's an error

答案 1 :(得分:0)

您也可以使用该类型的名称。

答案 2 :(得分:0)

创建反映类型的新值并进行类型断言:

...
default:
    typeOutValue := reflect.New(typeOut)

    if _, ok := typeOutValue.Interface().(*error); ok {
        defaultValues[i] = typeOutValue.Elem()
    } else {
        fmt.Println("type of return index ", i, " was not identified")
    }
}

switch的界面类型:

...
default:
    typeOutValue := reflect.New(typeOut)

    switch typeOutValue.Interface().(type) {
    case *error:
        defaultValues[i] = typeOutValue.Elem()
    default:
        fmt.Println("type of return index ", i, " was not identified")
    }

通过这种方式,您还可以处理(可以)并且希望使用的其他任何接口类型,使用更加惯用的Go代码并减少对reflect的依赖(或至少对它们的调用)包(开销等)。