En Go existen dos tipos de constantes — las no tipadas (untyped) y las tipadas (typed). Históricamente, esto ha estado relacionado con el deseo del lenguaje de hacer los sistemas de tipos flexibles y seguros, permitiendo al compilador detectar errores en el tiempo de compilación, así como asegurar la conversión de tipos solo donde sea permitido.
El problema surge cuando el programador no distingue estas dos categorías y confía en el comportamiento de la constante sin tener en cuenta los requisitos de tipo en las declaraciones de funciones e interfaces. Esto puede llevar a errores en la conversión entre tipos, errores inesperados de compilación o compatibilidad "saltando" inesperadamente al llamar a funciones.
La solución radica en una comprensión clara:
const x int = 42), el manejo posterior de esta constante está limitado al tipo especificado.Ejemplo de código:
const Pi = 3.14 // constante sin tipo const Answer int64 = 42 // constante con tipo func printInt(a int) { fmt.Println(a) } func main() { printInt(Pi) // Error: Pi no es int (pero se puede convertir explícitamente) printInt(int(Pi)) // Ok printInt(Answer) // Ok, ya que Answer es int64, y int64 a int — conversión explícita }
Características clave:
¿Se puede asignar una constante sin tipo a una variable de tipo int sin conversión si su valor es un float?
No. Aunque una constante sin tipo puede ser utilizada en una expresión de diferente tipo, intentar asignar una constante float a una variable de tipo int resultará en un error de compilación. Se requiere conversión explícita:
const Pi = 3.14 var x int = Pi // el compilador dará un error var y int = int(Pi) // Ok
¿El tipo de una constante sin tipo pasa a ser su tipo en la primera operación de asignación?
No, la constante no obtiene tipo hasta que se introduce en un contexto donde se espera un tipo específico, o se declara explícitamente. En otros casos, permanece como untyped.
¿Se pueden usar constantes numéricas grandes sin tipo para inicializar variables de menor tamaño, si los valores caben?
Sí, siempre que el valor en módulo se ajuste al rango del tipo objetivo. De lo contrario, el compilador generará un error de desbordamiento.
Ejemplo:
const Big = 1 << 62 var x int32 = Big // Error: Big no cabe en int32 var y int64 = Big // Ok
En un proyecto financiero complejo, los desarrolladores declararon varias constantes (porcentajes, coeficientes) como no tipadas. Un día, algunas funciones comenzaron a requerir float32 en lugar de float64. La adaptación automática de tipos llevó a la pérdida de precisión en los cálculos, lo que no se notó de inmediato.
Pros:
Contras:
En otra parte del sistema, todas las constantes se declaran con tipo explícito, y las conversiones se realizan explícitamente:
const Discount float64 = 0.05
Pros:
Contras: