-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Closed as duplicate of#45380
Description
Proposal Details
When I try to make a generic code where I have a case distinction for different generic types defined by interfaces, this can become very ugly and hard to read, because I can not make a type assertion for a generic type to another generic type, see the following example:
package main
import (
"fmt"
"reflect"
)
type Number interface {
float32 | float64 | complex64 | complex128 | int32 | int64
}
func main() {
a := 1.2
fmt.Printf("%v + 1 = %v\n", a, AddOne(a))
b := "1"
fmt.Printf("%v + 1 = %v\n", b, AddOne(b))
}
func AddOne[T any](a T) T {
switch reflect.TypeFor[T]() {
case reflect.TypeFor[float32]():
res := any(addOneNumber[float32](any(a).(float32))).(T)
return res
case reflect.TypeFor[float64]():
res := any(addOneNumber[float64](any(a).(float64))).(T)
return res
// This has to be done for each type in Number
default:
return addOneAny(a)
}
}
func addOneNumber[T Number](a T) T {
return a + 1
}
func addOneAny[T any](a T) T {
// Do something
var t T
return t
}
My proposal would be to allow casting of generic types similar to interfaces, e.g.
func AddOne[T any](a T) T {
aNumber, ok := a.(Number)
if ok {
return addOneNumber(aNumber)
} else {
return addOneAny(a)
}
}
I think this would make generic code easier to write and read and also less error prone.