英文:
Go reflect. How to check whether reflect.Type is an error type?
问题
我需要确定地检查一个 reflect.Type 是否是一个错误类型。
在 Go 的反射中,没有专门用于错误类型的 reflect kind。在检查类型错误时,通常采用正式/惯用的方式是什么?
以下是一个完整的示例代码:
// 根据函数的每个返回类型返回默认值的映射
// 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() // 函数返回值的数量
for i := 0; i < numOut; i++ {
typeOut := typeOfFunc.Out(i) // 第 i 个返回值的类型
switch typeOut.Kind() {
case reflect.Bool:
defaultValues[i] = reflect.ValueOf(true)
case reflect.Struct:
defaultValues[i] = reflect.New(typeOut).Elem()
// --> 如何确定 reflect.Type 是否是错误类型,使用 switch 或 if...
// case reflect.error: // 不存在
// var err error = nil
// defaultValues[i] = reflect.ValueOf(&err).Elem()
default:
// var err error = nil
// defaultValues[i] = reflect.ValueOf(&err).Elem()
fmt.Println("未识别返回值类型,索引为", i)
}
fmt.Println("返回值类型,索引为", i, typeOut, "kind", typeOut.Kind(), "是否可赋值给 err", typeOut.AssignableTo(reflect.TypeOf(errors.New(""))))
}
return defaultValues
}
你可以在 Go Playground 上运行这个示例代码。
英文:
I need to assuredly check whether a reflect.Type is an error.
There is no reflect kind for error. What is the formal/idiomatic manner to check for type error in go reflect?
//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
}
答案1
得分: 21
在Go语言中,error
并不是特殊的东西。error
只是一个预声明的接口类型,因此它在反射中没有自己的Kind。可以尝试以下代码:
errorInterface := reflect.TypeOf((*error)(nil)).Elem()
...
case reflect.Interface:
if typOute.Implements(errorInterface) // 它是一个错误
英文:
In Go error
is not something special. error
is just a predeclared interface type so it doesn't have its own Kind in reflect.
Try something along:
errorInterface := reflect.TypeOf((*error)(nil)).Elem()
...
case reflect.Interface:
if typOute.Implements(errorInterface) // it's an error
答案2
得分: 1
创建一个反射类型的新值,并进行类型断言:
...
default:
typeOutValue := reflect.New(typeOut)
if _, ok := typeOutValue.Interface().(*error); ok {
defaultValues[i] = typeOutValue.Elem()
} else {
fmt.Println("未识别返回索引的类型", i)
}
}
或者根据其接口类型使用switch
语句:
...
default:
typeOutValue := reflect.New(typeOut)
switch typeOutValue.Interface().(type) {
case *error:
defaultValues[i] = typeOutValue.Elem()
default:
fmt.Println("未识别返回索引的类型", i)
}
通过这种方式,您可以处理任何其他您可以(并且希望)特别关注的接口类型,使用更符合Go语言习惯的代码,并减少对reflect
包的依赖(包括开销等)。
英文:
Create a new value of the reflected type and do a type assertion:
...
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")
}
}
or switch
on its interface type:
...
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")
}
This way you can handle also any other interface type that you can (and want to) be particular about, with a more idiomatic Go code and reduced reliance on (or, at least, calls into) the reflect
package (overhead and all that).
答案3
得分: -1
你也可以直接使用类型的名称。
英文:
You could also just use the type's name.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论