golang,从另一个变量创建一个变量

时间:2017-09-11 17:48:48

标签: go reflection

我想:

  1. 创建另一个类型的变量。源变量是numeric(int,int16,float32,...)
  2. 对此变量进行一些简单的操作(+, - ,...)。
  3. 此代码可以正常工作:

    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\n", 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\n", v1, x1, x1)
    }
    

    结果:

    v=222.33, x=444.66 type x=float64
    v=33, x=66 type x=int
    

    是否有更优雅的解决方案(没有两个开关块)来完成同样的工作?

    感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

  

是否有更优雅的解决方案(没有两个开关块)来完成同样的工作?

没有。

你可以使用反射,但仍需要一个int,uints和float的开关。

(顺便说一下:别做这些事。)

答案 1 :(得分:0)

有更优雅,更有效的解决方案 - 不要使用interface{}作为接口来自接口{},否则会导致在装箱/取消装箱上花费资源(CPU /内存)。

// 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
}

如果你在函数中有更多的代码,你可以使用Go code generation为你想要的多种类型生成函数。

另一种选择是选择满足您所有需求的类型。例如,你可以只使用float64并在需要时将参数投射到它吗?