【问题标题】:Using reflection to call a function with a nil parameter results in a "Call using zero Value argument" panic使用反射调用带有 nil 参数的函数会导致“使用零值参数调用”恐慌
【发布时间】:2014-12-06 21:41:34
【问题描述】:

我正在尝试测试一个接受“错误”类型参数的函数。该函数在某些情况下应该会出现恐慌,我正在尝试测试场景。

但是,当我尝试在 nil 值上使用 reflect.Call 时(可以将其传递给接受“错误”类型的函数),它似乎会导致恐慌并显示以下消息:

reflect: Call using zero Value argument

我找到了以下帖子,但未能将其集成到我的功能中。

相关围棋游乐场:http://play.golang.org/p/cYQMQ6amPH

在上面的操场上,我希望对 InvocationCausedPanic(PanicOnErr, nil) 的调用返回 false,但是,来自反射的上述恐慌导致误报。

我可以对InvocationCausedPanicinvoke 函数进行任何修改以使其工作(同时保留其测试其他不能接受nil 作为参数的函数的能力 - 一个接受字符串的函数例如)?

也许问题在于函数的调用方式?

我尝试过InvocationCausedPanic(PanicOnErr, new(error))InvocationCausedPanic(PanicOnErr, error(nil)) 之类的东西,但无济于事。

感谢您的建议。

【问题讨论】:

    标签: testing reflection go


    【解决方案1】:

    如果参数值为nil,则使用函数参数类型的零值。

        if paramValue == nil {
            reflectedParams[paramIndex] = reflect.New(expectedType).Elem()
        } else {
            reflectedParams[paramIndex] = reflect.ValueOf(paramValue)
        }
    

    playground

    如果您计算反射值然后检查可分配性,您可以简化代码。通过此更改,不需要 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)
        }
    }
    

    【讨论】:

    • 感谢您的回答。我已经实施了您建议的更改,并且效果很好。然而,我刚刚想出了一个有点做作的案例,其中类型不兼容性检查不会因为不能接受 nil 的函数而失败。我认为这是因为在类型检查完成之前 nil 被转换为兼容的零值。你看到任何优雅的解决方案吗?相关游乐场:play.golang.org/p/qvytaeewtW
    • 啊,明白了。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-03
    • 2021-09-12
    • 2023-03-03
    • 2021-11-19
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多