I want to :
This code works fine :
package main
import (
"fmt"
"reflect"
)
func init1(v interface{}) interface{} {
switch reflect.ValueOf(v).Kind() {
case reflect.Int:
return int(0)
case reflect.Float32:
return float32(0)
case reflect.Float64:
return float64(0)
}
return nil
}
func sum(x, y interface{}) interface{} {
switch reflect.ValueOf(x).Kind() {
case reflect.Int:
return x.(int) + y.(int)
case reflect.Float32:
return x.(float32) + y.(float32)
case reflect.Float64:
return x.(float64) + y.(float64)
}
return nil
}
func main() {
v0 := 222.33
x0 := init1(v0)
x0 = sum(x0, v0)
x0 = sum(x0, v0)
fmt.Printf("v=%v, x=%v type x=%T
", v0, x0, x0)
v1 := 33
x1 := init1(v1)
x1 = sum(x1, v1)
x1 = sum(x1, v1)
fmt.Printf("v=%v, x=%v type x=%T
", v1, x1, x1)
}
Result :
v=222.33, x=444.66 type x=float64
v=33, x=66 type x=int
Is there a more elegant solution (without the two switch blocks) to do the same job ?
Thanks for your help.
Is there a more elegant solution (without the two switch blocks) to do the same job ?
No there is not.
You could use reflection but would still need a switch for int, uints and floats.
(Btw: Don't do such things.)
There is more elegant and more effective solution - do not use interface{}
as casting to/from interface{} will result in spending resources (CPU/memory) on boxing/unboxing.
// Bad solution - 11 lines of slow code
func sumBad(x, y interface{}) interface{} {
switch reflect.ValueOf(x).Kind() {
case reflect.Int:
return x.(int) + y.(int)
case reflect.Float32:
return x.(float32) + y.(float32)
case reflect.Float64:
return x.(float64) + y.(float64)
}
return nil
}
// Good solution - 9 lines of code that works faster
func sumInt(a, b int) int {
return a + b
}
func sumFloat32(a, b float32) float32 {
return a + b
}
func sumFloat64(a, b float64) float64 {
return a + b
}
If you have much more code inside the function you can use Go code generation to generate the functions for as many types as you want.
Another alternative would be to choose a type that cover all your needs. For example can you use just float64
and cast parameters to it whenever needed?