Wie finde ich den Typ eines Objekts in Go?

387

Wie finde ich den Typ eines Objekts in Go? In Python rufe ich nur typeofden Objekttyp ab. Gibt es in Go eine Möglichkeit, dasselbe zu implementieren?

Hier ist der Container, aus dem ich iteriere:

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

Ich kann in diesem Fall den Typ der Objektzeilen, bei denen es sich um ein Array von Zeichenfolgen handelt, nicht ermitteln.

Rahul
quelle
Die Standardreferenz funktioniert nicht in meinem Programm. Ich hätte den Quellcode meiner schlechten enthalten sollen.
Rahul
5
fmt.Printf("%T\n", var)
meh

Antworten:

470

Das Go-Reflection-Paket enthält Methoden zum Überprüfen des Variablentyps.

Das folgende Snippet druckt den Reflektionstyp einer Zeichenfolge, einer Ganzzahl und eines Gleitkommas aus.

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

}

Ausgabe:

Hello, playground
string
int
float64

Siehe: http://play.golang.org/p/XQMcUVsOja , um es in Aktion anzuzeigen.

Weitere Dokumentation hier: http://golang.org/pkg/reflect/#Type

dethtron5000
quelle
Ich denke, ich arbeite nicht für mich. Ich habe die Frage aktualisiert. Ich habe in diesem Fall ein Code-Snippet eingefügt.
Rahul
462

Ich habe drei Möglichkeiten gefunden, um den Typ einer Variablen zur Laufzeit zurückzugeben:

Verwenden der Zeichenfolgenformatierung

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

Mit Paket reflektieren

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

Verwenden von Typzusicherungen

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

Jede Methode hat einen anderen besten Anwendungsfall:

  • Zeichenfolgenformatierung - kurzer und geringer Platzbedarf (zum Importieren des Reflect-Pakets nicht erforderlich)

  • Reflect-Paket - Wenn Sie weitere Details zum Typ benötigen, haben Sie Zugriff auf die vollständigen Reflection-Funktionen

  • Typzusicherungen - Ermöglicht die Gruppierung von Typen, z. B. das Erkennen aller int32-, int64-, uint32- und uint64-Typen als "int".

Grzegorz Luczywo
quelle
3
Es scheint, dass Sie Variablen loswerden können t, so t := v.(type)wird v.(type)und _ = twird nicht mehr benötigt.
Akavall
3
Basierend auf einem Barebone-Benchmark ist der Reflect-
Mike Rapadas
case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String()). Fmt-Paket mit
Reflect
50

Verwenden Sie das Reflect- Paket:

Paketreflexion implementiert Laufzeitreflexion, sodass ein Programm Objekte mit beliebigen Typen bearbeiten kann. Die typische Verwendung besteht darin, einen Wert mit der statischen Typschnittstelle {} zu verwenden und seine dynamischen Typinformationen durch Aufrufen von TypeOf zu extrahieren, das einen Typ zurückgibt.

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

Produziert:

bool
string
int
float64
[]string

Spielplatz

Beispiel mit 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
}

Produziert:

bool
string
int
float64
string

Spielplatz

Internet
quelle
Reflect zeigt nur die Standardtypen an. Ich kann keine Elementtypen eines Listencontainers abrufen.
Rahul
Ich habe meine Antwort so aktualisiert, dass sie ein Stück Zeichenfolgen enthält. Reflect funktioniert für jeden Typ. Bitte lesen Sie die Dokumente: golang.org/pkg/reflect & blog.golang.org/laws-of-reflection sollte ausreichen, obwohl es viele SO-Fragen im Zusammenhang mit der Reflexion in Go gibt, die Ihnen ebenfalls helfen sollten.
Intermernet
2
ughhh, wie kann ich feststellen, ob der Typ eine Zeichenfolge ist? if reflect.TypeOf(err) == string?
Alexander Mills
43

So erhalten Sie eine Zeichenfolgendarstellung:

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

% T eine Go-Syntax-Darstellung des Werttyps

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

Ausgänge:

string
int
float64
bool
globby
quelle
sehr pragmatischer Ansatz +1
Bijan
16

Ich würde mich vom Nachdenken fernhalten. Paket. Verwenden Sie stattdessen% 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
quelle
13

Am besten verwenden Sie das Reflexionskonzept in Google.
reflect.TypeOfgibt Typ zusammen mit dem Paketnamen
reflect.TypeOf().Kind()gibt unterstrichenen Typ

Jiten
quelle
1
Dies ist meiner Meinung nach eine bessere Antwort
Ezio
9

Um es kurz zu machen, verwenden Sie bitte fmt.Printf("%T", var1) oder seine anderen Varianten im fmt-Paket.

pr-pal
quelle
4

Sie können den Typ jeder Variablen / Instanz zur Laufzeit überprüfen, indem Sie entweder die Paketfunktion "Reflect" TypeOfverwenden oder Folgendes verwenden 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
quelle
4

Um die Art der Felder in struct zu erhalten

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

Ausgabe

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

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

Negi Yogi
quelle
0

Sie können verwenden reflect.TypeOf.

  • Grundtyp (zB : int, string): Es wird sein Name zurückgegeben (zB : int, string)
  • struct: es ist etwas im Format zurückkehren wird <package name>.<struct name>(zB: main.test)
夜阑 听风
quelle
0

Wenn wir diese Variablen haben:

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

1: fmt.Printf% T- Format : Um diese Funktion zu verwenden, sollten Sie "fmt" importieren.

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

2: Reflect.TypeOf- Funktion : Um diese Funktion zu verwenden, sollten Sie " Reflect " importieren.

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

3: Reflect.ValueOf (X) .Kind () : Um diese Funktion zu verwenden, sollten Sie " Reflect " importieren.

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

Sie können verwenden: interface{}..(type)wie auf diesem Spielplatz

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
quelle
-2

reflektieren Paket kommt zur Rettung:

reflect.TypeOf(obj).String()

Überprüfen Sie diese Demo

Ismayil Niftaliyev
quelle