Skip to content

proposal: type assertion between generic types #73315

@Fabian836

Description

@Fabian836

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions