¿Cómo encontrar el tipo de un objeto en Go?


387

¿Cómo encuentro el tipo de un objeto en Go? En Python, solo uso typeofpara buscar el tipo de objeto. Del mismo modo, en Go, ¿hay alguna manera de implementar lo mismo?

Aquí está el contenedor desde el que estoy iterando:

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

No puedo obtener el tipo de líneas de objeto en este caso, que es una matriz de cadenas.


La referencia estándar no funciona en mi programa. Debería haber incluido el código fuente de mi mala.
Rahul

66
fmt.Printf("%T\n", var)
meh

Respuestas:


470

El paquete de reflexión Go tiene métodos para inspeccionar el tipo de variables.

El siguiente fragmento imprimirá el tipo de reflexión de una cadena, entero y flotante.

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

}

Salida:

Hello, playground
string
int
float64

ver: http://play.golang.org/p/XQMcUVsOja para verlo en acción.

Más documentación aquí: http://golang.org/pkg/reflect/#Type


reflexionar no está trabajando para mí. He actualizado la pregunta. He incluido un fragmento de código en este caso.
Rahul

462

Encontré 3 formas de devolver el tipo de una variable en tiempo de ejecución:

Usar formato de cadena

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

Usando paquete de reflejo

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

Usar aserciones de tipo

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

Cada método tiene un mejor caso de uso diferente:

  • formato de cadena: huella corta y baja (no es necesario para importar el paquete reflejado)

  • paquete de reflexión: cuando se necesitan más detalles sobre el tipo, tenemos acceso a las capacidades de reflexión completa

  • aserciones de tipo: permite agrupar tipos, por ejemplo, reconocer todos los tipos int32, int64, uint32, uint64 como "int"


3
Parece que puede deshacerse de la variable t, por lo que se t := v.(type)convierte v.(type)y _ = tya no es necesaria.
Akavall

3
Basado en un punto de referencia básico, el enfoque de reflexión es sorprendentemente más eficiente gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
Mike Rapadas

case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String()). paquete fmt usando el tipo de reflejo para imprimir
Fantasy_RQG

50

Use el paquete de reflexión :

Package reflect implementa la reflexión en tiempo de ejecución, lo que permite que un programa manipule objetos con tipos arbitrarios. El uso típico es tomar un valor con la interfaz de tipo estático {} y extraer su información de tipo dinámico llamando a TypeOf, que devuelve 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

Patio de recreo

Ejemplo 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

Patio de recreo


reflect solo muestra los tipos estándar. No puedo obtener tipos de elementos de un contenedor de listas.
Rahul

He actualizado mi respuesta para incluir una porción de cadenas. Reflect funciona para cualquier tipo. Lea los documentos: golang.org/pkg/reflect & blog.golang.org/laws-of-reflection debería ser suficiente, aunque hay muchas preguntas SO relacionadas con la reflexión en Go que también deberían ayudarlo.
Intermernet

2
ughhh, ¿cómo puedo determinar si el tipo es una cadena? if reflect.TypeOf(err) == string?
Alexander Mills

43

Para obtener una representación de cadena:

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

% T a Representación de sintaxis Go del tipo de valor

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

Salidas:

string
int
float64
bool

enfoque muy pragmático +1
Bijan

16

Me mantendría alejado del reflejo. paquete. En su lugar, use% 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

La mejor manera es usar el concepto de reflexión en Google.
reflect.TypeOfda el tipo junto con el nombre del paquete
reflect.TypeOf().Kind()da el tipo de subrayado


1
Creo que esta es una mejor respuesta
Ezio

9

Para ser breve, utilice fmt.Printf("%T", var1) o sus otras variantes en el paquete fmt.


4

Puede verificar el tipo de cualquier variable / instancia en tiempo de ejecución ya sea usando la TypeOffunción de paquetes "reflect" o usando 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

Para obtener el tipo de campos en 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())
   }
}

Salida

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

Ver en IDE https://play.golang.org/p/bwIpYnBQiE


0

puedes usar reflect.TypeOf.

  • tipo básico (por ejemplo: int, string): le proporcione su nombre (por ejemplo: int, string)
  • struct: se volverá algo en el formato <package name>.<struct name>(por ejemplo: main.test)

0

Si tenemos estas variables:

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

1: formato fmt.Printf% T : para usar esta función, debe importar "fmt"

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

2: función reflect.TypeOf : para utilizar esta función, debe importar "reflect"

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

3: reflect.ValueOf (X) .Kind () : para usar esta función, debe importar "reflect"

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

0

Puedes usar: interface{}..(type)como en este patio de recreo

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


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.