Come trovare il tipo di un oggetto in Go?


387

Come trovo il tipo di un oggetto in Go? In Python, utilizzo solo typeofper recuperare il tipo di oggetto. Allo stesso modo in Go, c'è un modo per implementare lo stesso?

Ecco il contenitore da cui sto ripetendo:

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

In questo caso non sono in grado di ottenere il tipo di righe dell'oggetto che è una matrice di stringhe.


Il riferimento standard non funziona nel mio programma. Avrei dovuto includere il mio codice sorgente male.
Rahul,

6
fmt.Printf("%T\n", var)
Meh,

Risposte:


470

Il pacchetto di riflessione Go ha metodi per ispezionare il tipo di variabili.

Il frammento seguente stamperà il tipo di riflesso di una stringa, intero e float.

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

}

Produzione:

Hello, playground
string
int
float64

vedi: http://play.golang.org/p/XQMcUVsOja per vederlo in azione.

Più documentazione qui: http://golang.org/pkg/reflect/#Type


riflettere non funziona per me. Ho aggiornato la domanda. In questo caso ho incluso lo snippet di codice.
Rahul,

462

Ho trovato 3 modi per restituire il tipo di una variabile in fase di esecuzione:

Utilizzo della formattazione delle stringhe

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

Utilizzo del pacchetto di riflessione

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

Utilizzando asserzioni di tipo

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

Ogni metodo ha un diverso caso d'uso migliore:

  • formattazione delle stringhe - ingombro ridotto e ridotto (non necessario per importare il pacchetto riflesso)

  • pacchetto riflettente: quando abbiamo bisogno di maggiori dettagli sul tipo, abbiamo accesso a tutte le funzionalità di riflessione

  • asserzioni di tipo: consente di raggruppare i tipi, ad esempio riconoscere tutti i tipi int32, int64, uint32, uint64 come "int"


3
Sembra che tu possa sbarazzarti della variabile t, così t := v.(type)diventa v.(type), e _ = tnon è più necessario.
Akavall,

3
Basato su un benchmark barebone, l'approccio riflettente è sorprendentemente più efficiente gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
Mike Rapadas

case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String()). pacchetto fmt utilizzando il tipo di riflessione per stampare
Fantasy_RQG

50

Usa il pacchetto di riflessione :

Il pacchetto riflessione implementa la riflessione di runtime, consentendo a un programma di manipolare oggetti con tipi arbitrari. L'uso tipico è di prendere un valore con l'interfaccia di tipo statico {} ed estrarre le sue informazioni di tipo dinamico chiamando TypeOf, che restituisce un tipo.

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

produce:

bool
string
int
float64
[]string

Terreno di gioco

Esempio usando 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
}

produce:

bool
string
int
float64
string

Terreno di gioco


reflection visualizza solo i tipi standard. Non sono in grado di ottenere tipi di elementi di un contenitore elenco.
Rahul,

Ho aggiornato la mia risposta per includere una fetta di stringhe. Reflect funziona per qualsiasi tipo. Leggi i documenti: golang.org/pkg/reflect & blog.golang.org/laws-of-reflection dovrebbe essere sufficiente, anche se ci sono molte domande SO relative alla riflessione in Go che dovrebbero aiutarti.
Intermernet,

2
come posso determinare se il tipo è una stringa? if reflect.TypeOf(err) == string?
Alexander Mills,

43

Per ottenere una rappresentazione in formato stringa:

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

% T una rappresentazione di sintassi Go del tipo del valore

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

Uscite:

string
int
float64
bool

approccio molto pragmatico +1
Bijan,

16

Starei lontano dal riflesso. pacchetto. Usa invece% 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)
 }

13

Il modo migliore è utilizzare il concetto di riflessione in Google.
reflect.TypeOfdà il tipo insieme al nome del pacchetto
reflect.TypeOf().Kind()dà il tipo di sottolineatura


1
Questa penso sia una risposta migliore
Ezio,

9

Per essere brevi, si prega di utilizzare fmt.Printf("%T", var1) o le sue altre varianti nel pacchetto fmt.


4

È possibile verificare il tipo di qualsiasi variabile / istanza in fase di esecuzione utilizzando la TypeOffunzione dei pacchetti "riflesso" o utilizzando 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)
}

4

Per ottenere il tipo di campi in 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())
   }
}

Produzione

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

Vedi in IDE https://play.golang.org/p/bwIpYnBQiE


0

puoi usare reflect.TypeOf.

  • tipo di base (ad esempio: int, string): verrà restituito il suo nome (per esempio: int, string)
  • struct: restituirà qualcosa nel formato <package name>.<struct name>(es main.test:)

0

Se abbiamo queste variabili:

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

1: formato fmt.Printf% T : per utilizzare questa funzione è necessario importare "fmt"

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

2: funzione reflection.TypeOf : per utilizzare questa funzione è necessario importare "rifletti"

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

3: reflection.ValueOf (X) .Kind () : per utilizzare questa funzione devi importare "rifletti"

fmt.Println(reflect.ValueOf(counter).Kind()) // counter type:  int

0

Puoi usare: interface{}..(type)come in questo parco giochi

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.