当前位置: 首页 > 知识库问答 >
问题:

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

丰誉
2023-03-14

虽然我知道在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)

虽然我知道可以使用defer和recover来更简单地测试函数,但我很好奇是否可以编写一个通用函数,该函数可以接受任何函数和参数,并确定它是否导致了恐慌(假设函数完成)。

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

共有1个答案

邹玮
2023-03-14

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

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)
}

游乐场

 类似资料:
  • 本文向大家介绍Go语言中使用反射的方法,包括了Go语言中使用反射的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Go语言中使用反射的方法。分享给大家供大家参考。具体实现方法如下: 创建实例如下: 完整代码如下: 希望本文所述对大家的Go语言程序设计有所帮助。

  • 本文向大家介绍Go语言中反射的正确使用,包括了Go语言中反射的正确使用的使用技巧和注意事项,需要的朋友参考一下 介绍 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型。 反射有两个问题,在使用前需要三思: 大量的使用反射会损失一定性能 Clear is better than clever. Reflectio

  • 虽然这个问题现在已经变得越来不明显,但不可否定的是,某些设备以及浏览器直到现在仍然不支持WebGL。 以下的方法可以帮助你检测当前用户所使用的环境是否支持WebGL,如果不支持,将会向用户提示一条信息。 请将https://github.com/mrdoob/three.js/blob/master/examples/jsm/WebGL.js引入到你的文件,并在尝试开始渲染之前先运行该文件。 if

  • 百度移动统计都支持哪些系统和设备? Q:百度移动统计都支持哪些系统和设备? A:百度移动统计支持Android、iOS系统以及使用这些系统的手机、平板等终端设备. 百度移动统计支持用户在国外的APP统计吗? Q:我们有一款面向印度和欧美用户的app,想请问在这种情况下接入百度统计,各维度统计数据是否准确? A: 百度移动统计支持用户在国外的app的统计需求,国外用户并不影响各维度数据统计的准确性,

  • 问题内容: 可以使用反射在抽象祖先类中创建派生类的实例吗? } 问题答案: 你可以这样做 版画 一种更常见的模式是使用Cloneable 版画 但是,应避免使用两者之一。通常,还有另一种方法可以满足您的需求,因此基础不会隐式地依赖于派生。

  • 问题内容: 我正在寻找一种有效的方法来检查切片是否是另一个切片的子集。我可以简单地遍历它们进行检查,但是我觉得必须有更好的方法。 例如 {1,2,3}是{1,2,3,4} 的子集{1,2,2}不是{1,2,3,4}的子集 有效执行此操作的最佳方法是什么? 谢谢! 问题答案: 我认为解决子集问题的最常见方法是通过地图。 检查重复值的能力相对罕见。上面的代码按要求解决了问题(请参阅:http : //