golang, create a variable from another one

huangapple go评论78阅读模式
英文:

golang, create a variable from another one

问题

我想要:

  1. 创建一个与另一个变量类型相同的变量。源变量是数值型的(int、int16、float32等)。
  2. 对这个变量进行一些简单的操作(+、-等)。

以下是有效的代码:

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

有没有更优雅的解决方案(不使用两个 switch 块)来完成相同的工作?

谢谢你的帮助。

英文:

I want to :

  1. Create a variable with the type of another one. The source variable is numeric (int, int16, float32, ...)
  2. Make some simple operations (+, -, ...) on this variable.

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\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)
}

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.

答案1

得分: 1

有没有更优雅的解决方案(不使用两个switch块)来完成相同的工作?

没有。

你可以使用反射,但仍然需要一个switch来处理int、uint和float。

(顺便说一句:不要做这样的事情。)

英文:

> 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.)

答案2

得分: 0

有一个更优雅和更有效的解决方案 - 不要使用interface{},因为将interface{}进行类型转换会导致资源(CPU/内存)的消耗。

// 不好的解决方案 - 11行慢速代码
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
}

// 好的解决方案 - 9行代码,速度更快
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代码生成为你想要的多种类型生成函数。

另一种选择是选择一个涵盖所有需求的类型。例如,你可以只使用float64,并在需要时将参数转换为它。

英文:

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?

huangapple
  • 本文由 发表于 2017年9月12日 01:48:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/46161603.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定