140 votes

Comment déterminer le type "réel" d'une valeur d'interface{} ?

Je n'ai pas trouvé de bonne ressource pour utiliser interface{} types. Par exemple

package main

import "fmt"

func weirdFunc(i int) interface{} {
    if i == 0 {
        return "zero"
    }
    return i
}
func main() {
    var i = 5
    var w = weirdFunc(5)

    // this example works!
    if tmp, ok := w.(int); ok {
        i += tmp
    }

    fmt.Println("i =", i)
}

Connaissez-vous une bonne introduction à l'utilisation de l'algorithme de Go ? interface{} ?

des questions spécifiques :

  • comment obtenir le "vrai" Type of w ?
  • Existe-t-il un moyen d'obtenir la représentation en chaîne d'un type ?
  • existe-t-il un moyen d'utiliser la représentation en chaîne d'un type pour convertir une valeur ?

7voto

Eugene Kulabuhov Points 126

Il existe plusieurs façons d'obtenir une représentation sous forme de chaîne de caractères d'un type. Les commutateurs peuvent également être utilisés avec les types d'utilisateur :

var user interface{}
user = User{name: "Eugene"}

// .(type) can only be used inside a switch
switch v := user.(type) {
case int:
    // Built-in types are possible (int, float64, string, etc.)
    fmt.Printf("Integer: %v", v)
case User:
    // User defined types work as well  
    fmt.Printf("It's a user: %s\n", user.(User).name)
}

// You can use reflection to get *reflect.rtype
userType := reflect.TypeOf(user)
fmt.Printf("%+v\n", userType)

// You can also use %T to get a string value
fmt.Printf("%T", user)

// You can even get it into a string
userTypeAsString := fmt.Sprintf("%T", user)

if userTypeAsString == "main.User" {
    fmt.Printf("\nIt's definitely a user")
}

Lien vers une aire de jeux : https://play.golang.org/p/VDeNDUd9uK6

2voto

daino3 Points 1699

Je vais proposer une façon de retourner un booléen en passant un argument d'une réflexion Kinds à un récepteur de type local (parce que je n'ai rien trouvé de tel).

Tout d'abord, nous déclarons notre type anonyme de type reflect.Value :

type AnonymousType reflect.Value

Ensuite, nous ajoutons un constructeur pour notre type local AnonymousType qui peut prendre n'importe quel type potentiel (comme une interface) :

func ToAnonymousType(obj interface{}) AnonymousType {
    return AnonymousType(reflect.ValueOf(obj))
}

Ensuite, nous ajoutons une fonction pour notre structure AnonymousType qui vérifie l'existence d'un reflect.Kind :

func (a AnonymousType) IsA(typeToAssert reflect.Kind) bool {
    return typeToAssert == reflect.Value(a).Kind()
}

Cela nous permet d'appeler ce qui suit :

var f float64 = 3.4

anon := ToAnonymousType(f)

if anon.IsA(reflect.String) {
    fmt.Println("Its A String!")
} else if anon.IsA(reflect.Float32) {
    fmt.Println("Its A Float32!")
} else if anon.IsA(reflect.Float64) {
    fmt.Println("Its A Float64!")
} else {
    fmt.Println("Failed")
}

Vous pouvez voir une version longue et fonctionnelle ici : https://play.golang.org/p/EIAp0z62B7

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X