Home > Article > Backend Development > Why do Go generics fail when a function returns a function?
I just started experimenting with generics on go and ran into a situation where I don't fully understand why it failed.
I refactored the following functions:
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) } }
Enter this:
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) } }
The unit test for this function failed with error: tests/utils/numberutils_test.go:82:50: Unable to infer t
. The source is:
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) } } }
I've changed a similar function from int to generic and I'm not sure why this function specifically doesn't work. I think it might have something to do with the function returning another function, but I can't exactly figure out why. Thanks.
Usually, the answer lies in Type Parameter Proposal:
The only type parameters that can be inferred are those used for function (non-type) input parameter types. If there are type parameters that are used only for the function's result parameter type, or only for the function body, you cannot use function parameter type inference to infer those type parameters.
in the case of
func PositivePercentageAbove[T constraints.Integer](above int) func(list []T) bool
Since the type parameter t
does not appear in the parameter list, the corresponding type parameter cannot be inferred.
The above is the detailed content of Why do Go generics fail when a function returns a function?. For more information, please follow other related articles on the PHP Chinese website!