Generic specification is supported in C++ and Rust, but why not Go?
What about generic type assertion?
func FormatNumber[T Number](t T, f byte, prec int) (s string) {
defer func() { recover() }()
switch v := reflect.ValueOf(t); v.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16,
reflect.Int32, reflect.Int64:
s = strconv.FormatInt(v.Int(), f, prec)
case reflect.Uint, reflect.Uint8, reflect.Uint16,
reflect.Uint32, reflect.Uint64, reflect.Uintptr:
s = strconv.FormatUint(v.Uint(), f, prec)
case reflect.Float32:
s = strconv.FormatFloat(v.Float(), f, prec, 32)
case reflect.Float64:
s = strconv.FormatFloat(v.Float(), f, prec, 64)
case reflect.Complex64:
s = strconv.FormatComplex(v.Complex(), f, prec, 64)
case reflect.Complex128:
s = strconv.FormatComplex(v.Complex(), f, prec, 128)
default:
s = v.String()
}
if f >= 'A' && f <= 'Z' {
s = ToUpper(s)
}
return s
}
becomes
func FormatNumber[T Number](t T, f byte, prec int) (s string) {
switch v := t.(type) {
case ~int, ~int8, ~int16, ~int32, ~int64:
s = strconv.FormatInt(int64(v), f, prec)
case ~uint, ~uint8, ~uint16, ~uint32, ~uint64, ~uintptr:
s = strconv.FormatUint(uint64(v), f, prec)
case ~float32:
s = strconv.FormatFloat(float64(v), f, prec, 32)
case ~float64:
s = strconv.FormatFloat(float64(v), f, prec, 64)
case ~complex64:
s = strconv.FormatComplex(complex128(v), f, prec, 64)
case ~complex128:
s = strconv.FormatComplex(complex128(v), f, prec, 128)
}
if f >= 'A' && f <= 'Z' {
s = ToUpper(s)
}
return s
}