2017-09-11 4 views
-1

Je veux une autre:golang, créer une variable d'un

  1. Créer une variable avec le type d'un autre. La variable source est numérique (int, int16, float32, ...)
  2. Effectuez des opérations simples (+, -, ...) sur cette variable.

Ce code fonctionne très bien:

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

Résultat:

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

Y at-il une solution plus élégante (sans les deux blocs de commutation) pour faire le même travail?

Merci pour votre aide.

Répondre

1

Y a-t-il une solution plus élégante (sans les deux blocs de commutation) pour faire le même travail?

Non, il n'y en a pas.

Vous pourriez utiliser la réflexion, mais vous auriez quand même besoin d'un commutateur pour int, uints et floats.

(BTW: Ne pas faire de telles choses.)

0

Il y a une solution plus élégante et plus efficace - ne pas utiliser interface{} comme coulée vers/depuis l'interface {} entraînera des ressources de dépenses (CPU/mémoire) sur la boxe/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 
} 

Si vous avez un code beaucoup plus dans la fonction que vous pouvez utiliser Go code generation pour générer les fonctions pour autant de types que vous voulez. Une autre alternative serait de choisir un type qui couvre tous vos besoins.

Par exemple pouvez-vous utiliser juste float64 et lancer des paramètres à chaque fois que nécessaire?