Como encontrar o tipo de um objeto no Go?


387

Como encontro o tipo de um objeto no Go? No Python, eu apenas uso typeofpara buscar o tipo de objeto. Da mesma forma, no Go, existe uma maneira de implementar o mesmo?

Aqui está o contêiner do qual estou iterando:

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

Eu não sou capaz de obter o tipo de linhas de objeto neste caso, que é uma matriz de seqüências de caracteres.


A referência padrão não está funcionando no meu programa. Eu deveria ter incluído o código fonte do meu mal.
— Rahul

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

Respostas:


470

O pacote de reflexão Go possui métodos para inspecionar o tipo de variáveis.

O trecho a seguir imprimirá o tipo de reflexão de uma sequência, número inteiro e número flutuante.

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

}

Resultado:

Hello, playground
string
int
float64

veja: http://play.golang.org/p/XQMcUVsOja para visualizá-lo em ação.

Mais documentação aqui: http://golang.org/pkg/reflect/#Type


refletir não está funcionando para mim. Eu atualizei a pergunta. Eu incluí um trecho de código nesse caso.
— Rahul

462

Eu encontrei 3 maneiras de retornar o tipo de uma variável em tempo de execução:

Usando formatação de string

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

Usando refletir pacote

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

Usando asserções de tipo

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

Todo método tem um melhor caso de uso diferente:

  • formatação de string - pegada curta e baixa (não é necessário importar o pacote refletido)

  • pacote refletir - quando precisarmos de mais detalhes sobre o tipo, teremos acesso aos recursos completos de reflexão

  • asserções de tipo - permite agrupar tipos, por exemplo, reconhecer todos os tipos int32, int64, uint32, uint64 como "int"


3
Parece que você pode se livrar da variável t, então t := v.(type)se torna v.(type)e _ = tnão é mais necessária.
— Akavall 28/02

3
Com base em uma referência barebones, a reflectir a abordagem é surpreendentemente mais eficiente gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
— Mike Rapadas

case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String()). pacote fmt usando refletir para imprimir o tipo
— Fantasy_RQG

50

Use o pacote de reflexão :

O pacote refletir implementa a reflexão em tempo de execução, permitindo que um programa manipule objetos com tipos arbitrários. O uso típico é pegar um valor com a interface de tipo estático {} e extrair suas informações de tipo dinâmico chamando TypeOf, que retorna um 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))
}

Produz:

bool
string
int
float64
[]string

Parque infantil

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

Produz:

bool
string
int
float64
string

Parque infantil


reflect apenas exibe os tipos padrão. Não consigo obter tipos de elementos de um contêiner de lista.
— Rahul

Atualizei minha resposta para incluir uma fatia de strings. Reflect funciona para qualquer tipo. Leia os documentos: golang.org/pkg/reflect & blog.golang.org/laws-of-reflection devem ser suficientes, embora existam muitas perguntas relacionadas à reflexão no Go que possam ajudá-lo.
— Intermernet

2
ughhh, como posso determinar se o tipo é uma string? if reflect.TypeOf(err) == string?
— Alexander Mills

43

Para obter uma representação de string:

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

% T uma representação de sintaxe Go do 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)
    }
}

Saídas:

string
int
float64
bool

abordagem muito pragmática +1
— Bijan

16

Eu ficaria longe da reflexão. pacote. Em vez disso, 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

A melhor maneira é usar o conceito de reflexão no Google.
reflect.TypeOfdá tipo junto com o nome do pacote
reflect.TypeOf().Kind()dá tipo sublinhado


11
Isso eu acho que é uma resposta melhor
— Ezio

9

Para ser breve, use fmt.Printf("%T", var1) ou suas outras variantes no pacote fmt.


4

Você pode verificar o tipo de qualquer variável / instância em tempo de execução, usando a TypeOffunção de pacotes "reflect" ou 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 obter o tipo de campos em 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())
   }
}

Resultado

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

Veja no IDE https://play.golang.org/p/bwIpYnBQiE


0

você pode usar reflect.TypeOf.

  • tipo básico (por exemplo: int, string): ele irá retornar o seu nome (por exemplo: int, string)
  • struct: retornará algo no formato <package name>.<struct name>(por exemplo main.test:)

0

Se tivermos essas variáveis:

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

1: formato fmt.Printf% T : para usar esse recurso, você deve importar "fmt"

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

2: função reflect.TypeOf : para usar este recurso, você deve importar "reflect"

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

3: reflect.ValueOf (X) .Kind () : para usar este recurso, você deve importar "reflect"

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

0

Você pode usar: interface{}..(type)como neste playground

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


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.