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.