我刚刚开始在 go 上尝试泛型,但遇到了一种我不完全理解它失败原因的情况。
我重构了以下函数:
func positivepercentageabove(above int) func(list []uint8) bool {
return func(list []uint8) bool {
acum := 0
for _, x := range list {
acum += int(x)
}
return (float64(acum) / float64(len(list)) * 100) >= float64(above)
}
}
进入此:
func positivepercentageabove[t constraints.integer](above int) func(list []t) bool {
return func(list []t) bool {
acum := 0
for _, x := range list {
acum += int(x)
}
return (float64(acum) / float64(len(list)) * 100) >= float64(above)
}
}
此函数的单元测试失败并出现错误:tests/utils/numberutils_test.go:82:50: 无法推断 t
。来源为:
func Test_TruePercentageAbove(t *testing.T) {
tables := []struct {
percentage int
list []uint8
output bool
}{
{percentage: 100, list: []uint8{1, 1, 1, 1}, output: true},
{percentage: 100, list: []uint8{1, 1, 0, 1}, output: false},
{percentage: 80, list: []uint8{1, 1, 1, 1, 0}, output: true},
{percentage: 90, list: []uint8{1, 1, 1, 1, 0}, output: false},
{percentage: 100, list: []uint8{1, 1, 1, 1, 0}, output: false},
{percentage: 40, list: []uint8{0, 1, 0, 1, 0, 1}, output: true},
{percentage: 60, list: []uint8{0, 1, 0, 1, 0, 1}, output: false},
{percentage: 70, list: []uint8{0, 1, 0, 1, 0, 1}, output: false},
}
for _, table := range tables {
result := utils.PositivePercentageAbove(table.percentage)(table.list)
if result != table.output {
t.Errorf("Slice %v with percentage above %v expected to return %v but returned %v", table.list, table.percentage, table.output, result)
}
}
}
我已经将类似的函数从 int 更改为泛型,我不确定为什么这个函数特别不起作用。我认为它可能与返回另一个函数的函数有某种关系,但我无法确切地弄清楚为什么。谢谢。
正确答案
通常,答案就在类型参数提案:
唯一可以推断的类型参数是那些用于函数(非类型)输入参数类型的参数。如果有一些类型参数仅用于函数的结果参数类型,或者仅用于函数体,则无法使用函数参数类型推断来推断这些类型参数。
如果是
func PositivePercentageAbove[T constraints.Integer](above int) func(list []T) bool
由于类型参数t
没有出现在参数列表中,因此无法推断出对应的类型参数。