Golang中如何将泛型数组类型作为函数参数传递
Go泛型合并多类型断言函数方案
问题原因
你之前直接改成customAssert func(array interface{})无法运行的核心原因是:Go中切片的类型是协变不兼容的,[]*pb.TypeA、[]*pb.TypeB不能直接隐式转换为interface{}类型,就算你强转后传入,函数内部也无法直接操作原切片类型,没有类型检查很容易出panic。
正确实现方案
方案1:使用Go 1.18+原生泛型(推荐)
这是最符合需求的实现,编译期就能做类型检查,不需要运行时断言:
- 首先给结构体加上泛型参数:
// T 是泛型参数,可以适配 *pb.TypeA、*pb.TypeB 等任意类型 type TestArgs[T any] struct { name string customAssert func(array []T) }
- 定义测试用例的时候直接指定对应泛型类型即可:
// TypeA 测试用例 testsA := []TestArgs[*pb.TypeA]{ { name: "Test A", customAssert: func(array []*pb.TypeA) { // 原有业务逻辑直接用,不需要任何修改 }, }, } // TypeB 测试用例 testsB := []TestArgs[*pb.TypeB]{ { name: "Test B", customAssert: func(array []*pb.TypeB) { // 原有业务逻辑直接用,不需要任何修改 }, }, }
如果需要把不同类型的测试用例放到同一个切片里,可以让TestArgs[T]实现一个公共接口,比如:
type Tester interface { Run() // 自定义执行方法,内部处理对应类型的断言逻辑 } func (t TestArgs[T]) Run() { // 这里实现你的测试执行逻辑,拿到对应类型的数组调用customAssert即可 } // 之后就可以把所有测试用例放到同一个[]Tester切片里 allTests := []Tester{ TestArgs[*pb.TypeA]{name: "Test A", customAssert: func(array []*pb.TypeA) { /* 逻辑 */ }}, TestArgs[*pb.TypeB]{name: "Test B", customAssert: func(array []*pb.TypeB) { /* 逻辑 */ }}, }
方案2:如果必须用interface{}兼容旧版本Go
需要配合运行时类型断言使用,注意只能在运行时做类型检查,编译期无法发现错误:
type TestArgs struct { name string customAssert func(array interface{}) } // 测试用例写法 tests := []TestArgs{ { name: "Test A", customAssert: func(array interface{}) { // 先断言类型,必须判断ok避免panic arr, ok := array.([]*pb.TypeA) if !ok { // 类型不匹配的错误处理逻辑,比如抛测试失败 return } // 原有业务逻辑操作arr即可 }, }, { name: "Test B", customAssert: func(array interface{}) { arr, ok := array.([]*pb.TypeB) if !ok { // 错误处理 return } // 原有业务逻辑 }, }, }
调用customAssert的时候,直接把对应类型的切片传进去即可,切片会自动转换为interface{}类型。
内容的提问来源于stack exchange,提问作者yyang
相关产品推荐
相关产品推荐

