'Returning Go Generic Type [duplicate]

The following fails to compile on line res = fmt.Sprintf("%s + %s", i, j) with the error: cannot use fmt.Sprintf("%s + %s", i, j) (value of type string) as type T in assignment

It does allow me to return an int and the code does compile and run if I simply return i + j.

I'm missing some fundamental understanding and need to be pointed in the correct direction.


import (
    "fmt"
    "reflect"
)

type Adder interface {
    string | int
}

func Add[T Adder](i, j T) T {
    var res T

    switch reflect.TypeOf(i).Name() {
    case "int":
        res = i + j
    case "string":
        res = fmt.Sprintf("%s + %s", i, j)
    }

    return res
}
func main() {
    it := Add(3, 4)
    st := Add("one", "two")

    fmt.Println("Int:", it)
    fmt.Println("Str:", st)
}


Solution 1:[1]

Take a look at what Add does for strings:

func Add[string](i, j string) string {
    var res string

    switch reflect.TypeOf(i).Name() {
    case "int":
        res = i + j
    case "string":
        res = fmt.Sprintf("%s + %s", i, j)
    }

    return res
}

This is ok. The expression i + j just concatenates two strings. Take a look at what Add does for int:

func Add[int](i, j int) int {
    var res int

    switch reflect.TypeOf(i).Name() {
    case "int":
        res = i + j
    case "string":
        res = fmt.Sprintf("%s + %s", i, j)
    }

    return res
}

This is a type error. It does not matter that the "string" branch is never taken at runtime—the entire function must typecheck!

(Note that Go does not actually instantiate generics by inserting the types—but you get the idea.)

Solution 2:[2]

The body of the generic function must be valid for all possible types. If res is int, the "string" case cannot be compiled. If res is string, both cases are valid expressions.

You can try this idea by declaring

type Adder interface {
    string 
}

and making the necessary changes. You still need to:

        res = T(fmt.Sprintf("%s + %s", i, j))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dietrich Epp
Solution 2 Burak Serdar