El lenguaje Go implementa una tipificación estática estricta. Esto significa que el tipo de cada variable es conocido en el momento de la compilación y el compilador no permite realizar operaciones con tipos incompatibles.
Existen dos tipos de conversión de tipos:
Ejemplo de conversión explícita:
var i int = 42 var f float64 = float64(i)
Ejemplo de type assertion:
var i interface{} = "hello" s, ok := i.(string) if ok { fmt.Println("Valor de cadena:", s) } else { fmt.Println("i no es una cadena") }
La conversión solo es posible entre tipos básicos compatibles (int → float64, rune → int32, pero string → int no es posible).
¿Puede un interface{} contener un valor nil, y cómo verificar correctamente que una variable de tipo interface es realmente nil?
Una trampa común es comparar un interfaz que contiene un valor nil con nil directamente:
var err error = nil var i interface{} = err fmt.Println(i == nil) // Se espera true, ¡pero será false!
La manera correcta:
Verificar que tanto el interfaz mismo como el valor interno son nil:
if i == nil || reflect.ValueOf(i).IsNil() { fmt.Println("i realmente es nil") }
Historia
En un proyecto de backend, un desarrollador intentó manejar diferentes errores a través de interface{}, comparándolos con nil. Como resultado, no pudo detectar correctamente el error: surgieron errores ocultos y una lógica incorrecta para devolver errores al cliente.
Historia
La migración entre float64 e int sin un cast explícito causaba pérdida de datos silenciosa: los valores se redondeaban o se trataban incorrectamente, ya que el compilador de Go requiere conversión explícita para tales operaciones.
Historia
En la deserialización de valores de interfaces al trabajar con map[string]interface{} (por ejemplo, desde JSON), los tipos inesperados de números (float64) llevaban a pánicos al utilizar type assertion sin una verificación adicional ok, el servicio caía debido a un error en tiempo de ejecución.