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