Comment trouver le type d'un objet dans Go?

387

Comment trouver le type d'un objet dans Go? En Python, j'utilise juste typeofpour récupérer le type d'objet. De même dans Go, existe-t-il un moyen de mettre en œuvre la même chose?

Voici le conteneur à partir duquel j'itère:

for e := dlist.Front(); e != nil; e = e.Next() {
    lines := e.Value
    fmt.Printf(reflect.TypeOf(lines))
}

Je ne suis pas en mesure d'obtenir le type des lignes d'objet dans ce cas qui est un tableau de chaînes.

Rahul
la source
La référence standard ne fonctionne pas dans mon programme. J'aurais dû inclure le code source de mon mauvais.
Rahul
6
fmt.Printf("%T\n", var)
meh

Réponses:

470

Le package de réflexion Go a des méthodes pour inspecter le type de variables.

L'extrait suivant imprimera le type de réflexion d'une chaîne, d'un entier et d'un flottant.

package main

import (
    "fmt"
    "reflect"
)

func main() {

    tst := "string"
    tst2 := 10
    tst3 := 1.2

    fmt.Println(reflect.TypeOf(tst))
    fmt.Println(reflect.TypeOf(tst2))
    fmt.Println(reflect.TypeOf(tst3))

}

Production:

Hello, playground
string
int
float64

voir: http://play.golang.org/p/XQMcUVsOja pour le voir en action.

Plus de documentation ici: http://golang.org/pkg/reflect/#Type

dethtron5000
la source
reflètent pas travailler pour moi. J'ai mis à jour la question. J'ai inclus un extrait de code dans ce cas.
Rahul
462

J'ai trouvé 3 façons de renvoyer le type d'une variable à l'exécution:

Utilisation de la mise en forme des chaînes

func typeof(v interface{}) string {
    return fmt.Sprintf("%T", v)
}

Utilisation du package Reflect

func typeof(v interface{}) string {
    return reflect.TypeOf(v).String()
}

Utilisation d' assertions de type

func typeof(v interface{}) string {
    switch v.(type) {
    case int:
        return "int"
    case float64:
        return "float64"
    //... etc
    default:
        return "unknown"
    }
}

Chaque méthode a un meilleur cas d'utilisation différent:

  • formatage de chaîne - encombrement court et faible (pas nécessaire pour importer le package de réflexion)

  • Forfait Reflect - lorsque vous avez besoin de plus de détails sur le type auquel nous avons accès à toutes les capacités de réflexion

  • assertions de type - permet de regrouper les types, par exemple reconnaître tous les types int32, int64, uint32, uint64 comme "int"

Grzegorz Luczywo
la source
3
Il semble que vous puissiez vous débarrasser des variables t, cela t := v.(type)devient v.(type)et _ = tn'est plus nécessaire.
Akavall
3
Basé sur un benchmark barebones, l'approche de réflexion est étonnamment plus efficace gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
Mike Rapadas
case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String()). package fmt utilisant la réflexion pour imprimer le type
Fantasy_RQG
50

Utilisez le reflet package:

Package refléter implémente la réflexion au moment de l'exécution, permettant à un programme de manipuler des objets avec des types arbitraires. L'utilisation typique consiste à prendre une valeur avec une interface de type statique {} et à extraire ses informations de type dynamique en appelant TypeOf, qui renvoie un Type.

package main

import (
    "fmt"
    "reflect"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Println(reflect.TypeOf(b))
    fmt.Println(reflect.TypeOf(s))
    fmt.Println(reflect.TypeOf(n))
    fmt.Println(reflect.TypeOf(f))
    fmt.Println(reflect.TypeOf(a))
}

Produit:

bool
string
int
float64
[]string

Terrain de jeux

Exemple utilisant ValueOf(i interface{}).Kind():

package main

import (
    "fmt"
    "reflect"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Println(reflect.ValueOf(b).Kind())
    fmt.Println(reflect.ValueOf(s).Kind())
    fmt.Println(reflect.ValueOf(n).Kind())
    fmt.Println(reflect.ValueOf(f).Kind())
    fmt.Println(reflect.ValueOf(a).Index(0).Kind()) // For slices and strings
}

Produit:

bool
string
int
float64
string

Terrain de jeux

Intermernet
la source
refléter n'affiche que les types standard. Je ne parviens pas à obtenir les types d'éléments d'un conteneur de liste.
Rahul
J'ai mis à jour ma réponse pour inclure une tranche de chaînes. Reflect fonctionne pour tout type. Veuillez lire les documents: golang.org/pkg/reflect & blog.golang.org/laws-of-reflection devrait suffire, bien qu'il existe de nombreuses questions SO liées à la réflexion dans Go qui devraient également vous aider.
Intermernet
2
ughhh, comment puis-je déterminer si le type est une chaîne? if reflect.TypeOf(err) == string?
Alexander Mills
43

Pour obtenir une représentation sous forme de chaîne:

Depuis http://golang.org/pkg/fmt/

% T une représentation de syntaxe Go du type de la valeur

package main
import "fmt"
func main(){
    types := []interface{} {"a",6,6.0,true}
    for _,v := range types{
        fmt.Printf("%T\n",v)
    }
}

Les sorties:

string
int
float64
bool
globby
la source
approche très pragmatique +1
Bijan
16

Je resterais loin du reflet. paquet. Utilisez plutôt% T

package main

import (
    "fmt"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Printf("%T\n", b)
    fmt.Printf("%T\n", s)
    fmt.Printf("%T\n", n)
    fmt.Printf("%T\n", f)
    fmt.Printf("%T\n", a)
 }
harold ramos
la source
13

Le meilleur moyen est d'utiliser le concept de réflexion dans Google.
reflect.TypeOfdonne le type avec le nom du package
reflect.TypeOf().Kind()donne le type de soulignement

Jiten
la source
1
Je pense que c'est une meilleure réponse
Ezio
9

Pour être bref, veuillez utiliser fmt.Printf("%T", var1) ou ses autres variantes dans le package fmt.

pr-pal
la source
4

Vous pouvez vérifier le type de n'importe quelle variable / instance au moment de l'exécution soit en utilisant la TypeOffonction de packages "Reflect" ou en utilisant fmt.Printf():

package main

import (
   "fmt"
   "reflect"
)

func main() {
    value1 := "Have a Good Day"
    value2 := 50
    value3 := 50.78

    fmt.Println(reflect.TypeOf(value1 ))
    fmt.Println(reflect.TypeOf(value2))
    fmt.Println(reflect.TypeOf(value3))
    fmt.Printf("%T",value1)
    fmt.Printf("%T",value2)
    fmt.Printf("%T",value3)
}
Kabeer Shaikh
la source
4

Pour obtenir le type de champs dans struct

package main

import (
  "fmt"
  "reflect"
)

type testObject struct {
  Name   string
  Age    int
  Height float64
}

func main() {
   tstObj := testObject{Name: "yog prakash", Age: 24, Height: 5.6}
   val := reflect.ValueOf(&tstObj).Elem()
   typeOfTstObj := val.Type()
   for i := 0; i < val.NumField(); i++ {
       fieldType := val.Field(i)
       fmt.Printf("object field %d key=%s value=%v type=%s \n",
          i, typeOfTstObj.Field(i).Name, fieldType.Interface(),
          fieldType.Type())
   }
}

Production

object field 0 key=Name value=yog prakash type=string 
object field 1 key=Age value=24 type=int 
object field 2 key=Height value=5.6 type=float64

Voir dans IDE https://play.golang.org/p/bwIpYnBQiE

negi Yogi
la source
0

vous pouvez utiliser reflect.TypeOf.

  • type de base (par exemple: int, string): il retournera son nom (par exemple: int, string)
  • struct: elle retourne quelque chose dans le format <package name>.<struct name>(par exemple: main.test)
夜阑 听风
la source
0

Si nous avons ces variables:

var counter int = 5
var message string  = "Hello"
var factor float32 = 4.2
var enabled bool = false

1: format fmt.Printf% T : pour utiliser cette fonction, vous devez importer "fmt"

fmt.Printf("%T \n",factor )   // factor type: float32

2: fonction reflect.TypeOf : pour utiliser cette fonction, vous devez importer "reflect"

fmt.Println(reflect.TypeOf(enabled)) // enabled type:  bool

3: reflect.ValueOf (X) .Kind () : pour utiliser cette fonction, vous devez importer "reflect"

fmt.Println(reflect.ValueOf(counter).Kind()) // counter type:  int
Hamed Naeemaei
la source
0

Vous pouvez utiliser: interface{}..(type)comme dans cette aire de jeux

package main
import "fmt"
func main(){
    types := []interface{} {"a",6,6.0,true}
    for _,v := range types{
        fmt.Printf("%T\n",v)
        switch v.(type) {
        case int:
           fmt.Printf("Twice %v is %v\n", v, v.(int) * 2)
        case string:
           fmt.Printf("%q is %v bytes long\n", v, len(v.(string)))
       default:
          fmt.Printf("I don't know about type %T!\n", v)
      }
    }
}
Hasan A Yousef
la source
-2

Le paquet Reflect vient à la rescousse:

reflect.TypeOf(obj).String()

Regardez cette démo

Ismayil Niftaliyev
la source