Cómo saber el tipo de un objeto en Go: 5 errores fatales de principiante y cómo evitarlos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: «¿Y qué clase de bicho es este?»

\n\n

Imagina: estás escribiendo en Go una función que recibe interface{}. Dentro de esta función quieres entender qué datos te han llegado. ¿Un número? ¿Una cadena? ¿O quizás alguna estructura personalizada? Si vienes de Python o JavaScript, donde se puede saber el tipo en una línea (type() o typeof), en Go te espera una pequeña sorpresa. Go es un lenguaje de tipado estricto, y no se puede «palpar» el tipo de un objeto así nomás.

\n\n

La pregunta «How to find the type of an object in Go?» en Stack Overflow ha acumulado decenas de miles de visitas. Esto significa que incluso desarrolladores experimentados a veces se confunden. En este artículo analizaremos los errores principales que cometen los principiantes (y no solo) al determinar el tipo en Go, y mostraremos cómo evitarlos. Aprenderás sobre reflect.TypeOf, fmt.Sprintf con %T, type assertion y type switch.

\n\n

Método n.º 1: Lo más simple — fmt y %T (pero con trampa)

\n\n

La forma más rápida de saber el tipo es usar el paquete fmt y el formato %T. Esto funciona, pero muchos olvidan que fmt no es una varita mágica, sino solo un envoltorio sobre 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

Todo simple, ¿verdad? Pero aquí está el error: %T devuelve una cadena, no un tipo. No podrás realizar ninguna operación con ella, excepto mostrarla en pantalla. Si necesitas verificar si el objeto es un número y hacer algo al respecto, %T no te servirá. Este es el primer error: usar %T donde se necesita lógica de bifurcación.

\n\n

Cómo evitarlo

\n

Usa %T solo para depuración o registro de logs. Para verificar tipos en el código, utiliza type assertion o type switch (más adelante).

\n\n

Método n.º 2: El paquete reflect — potente, pero peligroso

\n\n

El paquete reflect es el kit de caballero para la reflexión en Go. El método más popular es 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 la solución ideal. Pero aquí los principiantes cometen el segundo error: confunden Kind() y Name().

\n\n
    \n
  • Name() — devuelve el nombre del tipo (por ejemplo, int, string, MyStruct).
  • \n
  • Kind() — devuelve la «categoría» base (por ejemplo, int, struct, slice).
  • \n
\n\n

Para los tipos incorporados coinciden, pero para los personalizados no. Por ejemplo, si declaras type MyInt int, entonces Name() devolverá MyInt, y Kind() devolverá int. Si solo verificas Kind(), podrías pasar por alto un tipo personalizado.

\n\n

Cómo evitarlo

\n

Siempre pregúntate: «¿Me importa el tipo exacto o solo la categoría?» Si necesitas el tipo exacto (por ejemplo, para serialización), usa Name(). Si solo necesitas saber que es un número, usa Kind().

\n\n

Método n.º 3: Type Assertion — un clásico (y error de pánico)

\n\n

Type assertion (afirmación de tipo) es una forma de «extraer» un tipo concreto de interface{}. Se ve así:

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

¿Cuál es el error? Si x resulta

Blogs

Book Recommendations