Como descobrir o tipo de um objeto em Go: 5 erros fatais de iniciante e como evitá-los

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: "E que bicho é esse?"

\n\n

Imagine: você está escrevendo uma função em Go que recebe um interface{}. Dentro dessa função, você quer entender que tipo de dados chegou até você. Um número? Uma string? Ou talvez alguma estrutura personalizada? Se você veio do Python ou JavaScript, onde o tipo pode ser descoberto em uma linha (type() ou typeof), então em Go você terá uma pequena surpresa. Go é uma linguagem de tipagem forte, e não é tão simples "sentir" o tipo de um objeto.

\n\n

A pergunta "How to find the type of an object in Go?" no Stack Overflow acumulou dezenas de milhares de visualizações. Isso significa que até desenvolvedores experientes às vezes se confundem. Neste artigo, vamos abordar os principais erros que iniciantes (e não só) cometem ao determinar o tipo em Go e mostrar como evitá-los. Você aprenderá sobre reflect.TypeOf, fmt.Sprintf com %T, type assertion e type switch.

\n\n

Método #1: O mais simples — fmt e %T (mas com um truque)

\n\n

A maneira mais rápida de descobrir o tipo é usar o pacote fmt e o formato %T. Isso funciona, mas muitos esquecem que fmt não é uma varinha mágica, mas apenas um invólucro sobre o reflect.

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    var x interface{} = 42\n    fmt.Printf("Tipo: %T\\n", x) // Tipo: int\n\n    var s interface{} = "hello"\n    fmt.Printf("Tipo: %T\\n", s) // Tipo: string\n}\n
\n\n

Tudo simples, certo? Mas o erro é o seguinte: %T retorna uma string, não um tipo. Você não pode realizar nenhuma operação com ela, exceto exibi-la na tela. Se você precisa verificar se o objeto é um número e fazer algo — %T não vai ajudar. Este é o primeiro erro: usar %T onde é necessária lógica de ramificação.

\n\n

Como evitar

\n

Use %T apenas para depuração ou saída de logs. Para verificação de tipos no código, utilize type assertion ou type switch (sobre eles abaixo).

\n\n

Método #2: Pacote reflect — poderoso, mas perigoso

\n\n

O pacote reflect é o kit de ferramentas para reflexão em Go. O método mais popular é reflect.TypeOf().

\n\n
package main\n\nimport (\n    "fmt"\n    "reflect"\n)\n\nfunc main() {\n    var x interface{} = 42\n    t := reflect.TypeOf(x)\n    fmt.Println(t) // int\n    fmt.Println(t.Name()) // int\n    fmt.Println(t.Kind()) // int\n}\n
\n\n

Parece a solução ideal. Mas aqui os iniciantes cometem o segundo erro: confundir Kind() e Name().

\n\n
    \n
  • Name() — retorna o nome do tipo (por exemplo, int, string, MyStruct).
  • \n
  • Kind() — retorna o "tipo" base (por exemplo, int, struct, slice).
  • \n
\n\n

Para tipos nativos, eles coincidem, mas para tipos personalizados, não. Por exemplo, se você declarar type MyInt int, então Name() retornará MyInt, e Kind() retornará int. Se você verificar apenas Kind(), pode acabar ignorando o tipo personalizado.

\n\n

Como evitar

\n

Sempre se pergunte: "O tipo exato é importante ou apenas a categoria?" Se precisar do tipo exato (por exemplo, para serialização) — use Name(). Se precisar apenas entender que é um número — use Kind().

\n\n

Método #3: Type Assertion — o clássico (e o erro de pânico)

\n\n

Type assertion (afirmação de tipo) é uma forma de "extrair" um tipo específico de um interface{}. Fica assim:

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    var x interface{} = 42\n    value := x.(int) // afirmamos que x é int\n    fmt.Println(value + 10) // 52\n}\n
\n\n

Qual é o erro? Se x não for

Blogs

Book Recommendations