为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中使用反射检查兼容类型

在 Go 中使用反射检查兼容类型

Go
慕妹3146593 2021-08-23 15:49:08
虽然我知道在 Go 中恐慌可能不是惯用的,但我想测试以确保函数在某些条件下而不是在其他条件下发生恐慌。函数的一个例子。func PanicOnErr(potentialErr error) {    if potentialErr != nil {        panic(potentialErr)    }}以下是检查函数是否会 panic 的实现。func InvocationCausedPanic(f interface{}, params ...interface{}) bool {    // Obtain the function's signature.    reflectedFunc := reflect.ValueOf(f)    funcType := reflect.TypeOf(f)    if funcType.NumIn() != len(params) {        panic("InvocationCausedPanic called with a function and an incorrect number of parameter(s).")    }    reflectedParams := make([]reflect.Value, len(params))    for paramIndex, paramValue := range params {        expectedType := funcType.In(paramIndex)        actualType := reflect.TypeOf(paramValue)        if actualType != expectedType {            errStr := fmt.Sprintf("InvocationCausedPanic called with a mismatched parameter type [parameter #%v: expected %v; got %v].", paramIndex, expectedType, actualType)            panic(errStr)        }        reflectedParams[paramIndex] = reflect.ValueOf(paramValue)    }    return invoke(reflectedFunc, reflectedParams)}func invoke(reflectedFunc reflect.Value, reflectedParams []reflect.Value) (panicked bool) {    defer func() {        if r := recover(); r != nil {            panicked = true        }    }()    reflectedFunc.Call(reflectedParams)    return}调用以下任一方法都会导致类型检查失败。InvocationCausedPanic(PanicOnErr, errors.New("Some error."))InvocationCausedPanic(PanicOnErr, nil)但是,似乎可以PanicOnErr使用两者进行调用,nil并且可以通过调用生成某些内容errors.New(似乎是 类型*errors.errorString)。因此,有没有办法检查某个参数的类型是否适合调用某个函数?虽然我知道可以使用 defer 和 recovery 来更简单地测试函数,但我很好奇是否可以编写一个通用函数来接受任何函数和参数并确定它是否导致了恐慌(假设功能完成)。
查看完整描述

1 回答

?
胡子哥哥

TA贡献1825条经验 获得超6个赞

使用此函数确定参数是否兼容:


func compatible(actual, expected reflect.Type) bool {

  if actual == nil {

    k := expected.Kind()

    return k == reflect.Chan || 

           k == reflect.Func || 

           k == reflect.Interface || 

           k == reflect.Map || 

           k == reflect.Ptr || 

           k == reflect.Slice

  }

  return actual.AssignableTo(expected)

}


查看完整回答
反对 回复 2021-08-23
  • 1 回答
  • 0 关注
  • 158 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信