1
虽然我知道在Go中可能不会习惯性地恐慌,但我想测试以确保函数在某些情况下发生混乱,而不是在其他情况下发生混乱。在Go中使用反射来检查兼容类型
函数的一个例子。
func PanicOnErr(potentialErr error) {
if potentialErr != nil {
panic(potentialErr)
}
}
以下是检查函数是否会出现混乱的实现。
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)
然而,似乎有可能同时使用nil
和东西叫PanicOnErr
通过调用errors.New
生成(似乎是*errors.errorString
类型)。
因此,有没有办法检查某些参数的类型是否适合调用某个函数?
尽管我知道可以使用延迟和恢复来更简单地测试函数,但我很好奇是否可以编写一个通用函数来接受任何函数和参数,并确定它是否导致恐慌(假设函数完成)。
相关转到游乐场: http://play.golang.org/p/qUG7OGuIbD
谢谢。这解决了类型兼容性问题! – Deity 2014-10-12 00:38:01
再次感谢您的帮助。我问过一个后续问题;也许你也会知道答案。 http://stackoverflow.com/questions/26321115 – Deity 2014-10-12 02:04:48