英文:
Using reflection to call a function with a nil parameter results in a "Call using zero Value argument" panic
问题
我正在尝试测试一个接受"error"类型参数的函数。在某些情况下,该函数应该引发panic,我正在尝试测试这些场景。
然而,当我尝试在一个接受"type error"参数的函数中使用reflect.Call
来调用一个nil
值时,似乎会导致panic,并显示以下消息:
reflect: 使用零值参数进行调用
我找到了以下帖子,但我无法将其整合到我的函数中。
- https://groups.google.com/forum/#!topic/golang-nuts/apNcACpl_fI
- https://groups.google.com/forum/#!topic/golang-nuts/WOUft8EZQ1I
相关的Go Playground: http://play.golang.org/p/cYQMQ6amPH
在上面的playground中,我希望调用InvocationCausedPanic(PanicOnErr, nil)
返回false
,然而,reflect引发的panic导致了一个错误的结果。
我是否可以对InvocationCausedPanic
或invoke
函数进行任何修改,使其正常工作(同时保留其测试其他不能接受nil
作为参数的函数的能力,比如接受字符串的函数)?
也许问题出在函数的调用方式上?
我尝试过像InvocationCausedPanic(PanicOnErr, new(error))
或InvocationCausedPanic(PanicOnErr, error(nil))
这样的方法,但都没有成功。
感谢任何建议。
英文:
I'm trying to test a function that accepts a parameter of the type "error". The function should panic under certain situations and I'm trying to test scenarios.
However, when I try to use reflect.Call
on a nil
value (which can be passed into a function that accepts something of type "error"), it seems to result in a panic with the following message:
reflect: Call using zero Value argument
I have found the following posts but I am failing to integrate it into my function.
- https://groups.google.com/forum/#!topic/golang-nuts/apNcACpl_fI
- https://groups.google.com/forum/#!topic/golang-nuts/WOUft8EZQ1I
Relevant Go Playground: http://play.golang.org/p/cYQMQ6amPH
In the playground above, I would like the call to InvocationCausedPanic(PanicOnErr, nil)
to return false
, however, the above panic from reflect is causing a false positive.
Are there any modifications I can make to the InvocationCausedPanic
or the invoke
functions to make this work (while retaining its ability to test other functions that cannot accept nil
as an argument - a function that accepts a string for instance)?
Perhaps the issue is in how the function is called?
I've tred things like InvocationCausedPanic(PanicOnErr, new(error))
or InvocationCausedPanic(PanicOnErr, error(nil))
to no avail.
Thanks for any advice.
答案1
得分: 4
如果参数值为nil,则使用函数参数类型的零值。
if paramValue == nil {
reflectedParams[paramIndex] = reflect.New(expectedType).Elem()
} else {
reflectedParams[paramIndex] = reflect.ValueOf(paramValue)
}
你可以简化代码,如果你计算了反射值,然后检查可分配性。通过这个改变,compatible
函数就不再需要了。
for paramIndex, paramValue := range params {
if paramValue == nil {
reflectedParams[paramIndex] = reflect.New(expectedType).Elem()
} else {
reflectedParams[paramIndex] = reflect.ValueOf(paramValue)
}
expectedType := funcType.In(paramIndex)
actualType := reflectedParams[paramIndex].Type()
if !actualType.AssignableTo(expectedType) {
errStr := fmt.Sprintf("InvocationCausedPanic called with a mismatched parameter type [parameter #%v: expected %v; got %v].", paramIndex, expectedType, actualType)
panic(errStr)
}
}
<kbd>playground</kbd>
英文:
If the parameter value is nil, then use a zero value of the function parameter type.
if paramValue == nil {
reflectedParams[paramIndex] = reflect.New(expectedType).Elem()
} else {
reflectedParams[paramIndex] = reflect.ValueOf(paramValue)
}
<kbd>playground</kbd>
You can simplify the code if you compute the reflect value and then check assignability. With this change, the compatible
function is not required.
for paramIndex, paramValue := range params {
if paramValue == nil {
reflectedParams[paramIndex] = reflect.New(expectedType).Elem()
} else {
reflectedParams[paramIndex] = reflect.ValueOf(paramValue)
}
expectedType := funcType.In(paramIndex)
actualType := reflectedParams[paramIndex].Type()
if !actualType.AssignableTo(expectedType) {
errStr := fmt.Sprintf("InvocationCausedPanic called with a mismatched parameter type [parameter #%v: expected %v; got %v].", paramIndex, expectedType,actualType)
panic(errStr)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论