我希望能够创建一个结构体,该结构体具有一个可以保存任何类型值的字段,只要该类型可以与通常的比较运算符(
<
、<=
、>
等进行比较)。 .)。我知道有 contraints.Ordered
,但该接口仅限于用作类型约束。
这是我想使用此界面的示例:
func TestMergeSort(t *testing.T) {
type TestCase[T constraints.Ordered] struct {
input []T
expected []T
}
intTests := map[string]TestCase[int] {
"#1": {
input: []int{3,2,5,1,4,6},
expected: []int{1,2,3,4,5,6},
},
}
stringTests := map[string]TestCase[string] {
"#2": {
input: []string{"hello","bonjour"},
expected: []string{"bonjour","hello"},
},
}
// test int sorting
for name, test := range intTests {
t.Run(name, func(t *testing.T) {
output := MergeSort(test.input)
if !cmp.Equal(test.expected, output) {
t.Fatalf(`Expected %v got %v`, test.expected, output)
}
})
}
// test string sorting
for name, test := range stringTests {
t.Run(name, func(t *testing.T) {
output := MergeSort(test.input)
if !cmp.Equal(test.expected, output) {
t.Fatalf(`Expected %v got %v`, test.expected, output)
}
})
}
}
我希望能够将 int 和 string 测试用例分组到单个变量下。但这似乎不可能使用具有
constraints.Ordered
约束的泛型,因为我必须先实例化泛型类型,然后才能使用它。
理想情况下,我想将其减少为这样的:
func TestMergeSortTable(t *testing.T) {
// What I'm looking for is something that can replace the `Sortable` interface example below
type TestCase struct {
input []Sortable
expected []Sortable
}
tests := map[string]TestCase {
"#1": {
input: []int{3,2,5,1,4,6},
expected: []int{1,2,3,4,5,6},
},
"#2": {
input: []string{"hello","bonjour"},
expected: []string{"bonjour","hello"},
},
}
// test int and string sorting in a single loop
for name, test := range tests {
t.Run(name, func(t *testing.T) {
output := MergeSort(test.input)
if !cmp.Equal(test.expected, output) {
t.Fatalf(`Expected %v got %v`, test.expected, output)
}
})
}
}
PS:
MergeSort
的函数签名,以防需要
func MergeSort[T constraints.Ordered](arr []T)(res []T) {
// sorting logic here
}
为测试用例声明一个接口,而不是切片元素。将运行逻辑实现为测试用例方法。
type sortTestCase[T constraints.Ordered] struct {
name string
input []T
want []T
}
func (tc sortTestCase[T]) run(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
got := slices.Clone(tc.input)
slices.Sort(got)
if !reflect.DeepEqual(got, tc.want) {
t.Fatalf(`got %v want %v`, got, tc.want)
}
})
}
var sortTestCases = []interface{ run(t *testing.T) }{
sortTestCase[int]{
name: "ints",
input: []int{3, 2, 5, 1, 4, 6},
want: []int{1, 2, 3, 4, 5, 6},
},
sortTestCase[string]{
name: "strings",
input: []string{"hello", "bonjour"},
want: []string{"bonjour", "hello"},
},
}
func TestSort(t *testing.T) {
for _, tc := range sortTestCases {
tc.run(t)
}
}