Home  >  Article  >  Backend Development  >  Why do Go generics fail when a function returns a function?

Why do Go generics fail when a function returns a function?

王林
王林forward
2024-02-05 21:33:11435browse

为什么当函数返回一个函数时 Go 泛型会失败?

Question content

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.


Correct Answer


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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete