Introducción
En un artículo anterior conocimos las constantes en Go y vimos cómo representan valores fijos evaluados en tiempo de compilación.
De forma intencionada, en ese articulo no entré en el papel que juegan los tipos de datos. Esa omisión no fue accidental: Go permite que algunas constantes no tengan un tipo asociado desde el momento en que se declaran.
La pregunta natural es, ¿qué ocurre cuando queremos que una constante sí tenga un tipo fijo desde su declaración? ¿Cómo y cuándo entra el sistema de tipos en juego?.
En este artículo vas a entender qué significa que una constante sea tipada o no tipada, en qué situaciones se aplica cada una, y cómo esta distinción influye directamente en la claridad, la seguridad y el diseño del código en Go.
El punto de partida: constantes sin tipo
Aquí declaro algunas constantes sin hacer mención explicita a su tipo:
const x = 10 // sin tipo
const pi = 3.14159 // sin tipo
const saludo = "hola" // sin tipo
Esta ausencia de tipo otorga una flexibilidad muy poderosa: el mismo valor puede usarse en muchos contextos diferentes sin necesidad de conversiones explícitas.
Por ejemplo, cuando declaras x, ésta no tiene todavía un tipo concreto. No es int, ni int64, ni float64. Es simplemente el valor literal 10, conocido por el compilador en tiempo de compilación, y disponible para ser usado en distintos contextos. Esto permite hacer algo muy potente:
var a int = x // se comporta como int
var b int64 = x // se comporta como int64
var c float64 = x // se comporta como float64
var d uint8 = x // se comporta como uint8 (porque 10 cabe)
Fíjate en lo que ocurre: el mismo valor de x puede adaptarse a distintos tipos sin conversiones explícitas, siempre que el valor sea representable en este tipo.
Todo esto ocurre en tiempo de compilación. El compilador verifica que el valor sea representable en el tipo destino.
Este comportamiento es exclusivo de las constantes. Las variables no funcionan así, como ya vimos en el articulo sobre variables en Go.
Constantes tipadas
Una constante se convierte en constante tipada cuando su tipo de dato queda fijado. Esto puede ocurrir de dos formas:
Tipado explícito
Puedes indicar el tipo directamente en la declaración:
const MaxRetries int = 5
const Timeout int64 = 30
const Pi float64 = 3.141592653589793
Desde el instante que se declara, la constante es de ese tipo y punto. No hay vuelta atrás.
Ejemplo:
var a int = MaxRetries // correcto
var b int64 = MaxRetries // cannot use x (constant 5 of type int) as int64 value in variable declaration
El compilador ya no puede adaptar el valor a otro tipo, porque el tipo ha quedado fijado desde la misma declaración de la constante.
Tipado por contexto
Una constante no tipada adquiere un tipo solo en el momento en que se usa, y ese tipo depende del contexto en el que aparece.
Ejemplo:
const x = 10
var a int = x
var b int64 = x
Aquí ocurre algo importante:
xes una constante sin tipo- al asignar
xa la variablea, el compilador la interpreta comoint - al asignar
xa la variableb, el compilador la interpreta comoint64 xno deja de ser una constante sin tipo, pero se interpreta como uninto comoint64dependiendo del contexto
Este matiz es sutil, pero fundamental para entender uno de los conceptos mas elegantes -y a menudo mal entendidos- del sistema de tipos de Go.
Constantes tipadas vs no tipadas
La diferencia entre constantes tipadas y no tipadas no está en el valor de inicialización, sino en la flexibilidad del tipo.
Veamos esta tabla comparativa:
| Característica | Constante sin tipo | Constante tipada |
|---|---|---|
| ¿Tiene tipo fijo? | No | Sí, desde la declaración |
| ¿Se adapta al contexto? | Sí, a cualquier tipo compatible | No, solo su tipo declarado |
| Flexibilidad | Muy alta | Baja |
| ¿Cuándo adquiere tipo? | Cuando el contexto lo exige (en compilación) | En la propia declaración |
Por qué Go permite constantes sin tipo
Las constantes sin tipo son una herramienta del diseño de Go muy meditada. Tienen varios usos:
Permiten expresar valores universales de forma natural:
const Zero = 0
const One = 1
const Pi = 3.14159
Evitan conversiones explícitas por todas partes:
time.Sleep(500 * time.Millisecond) // 500 es sin tipo, se adapta sin problemas
Y finalmente, mantienen total seguridad en tiempo de compilación:
const Enorme = 1e100
var x int64 = Enorme // cannot use Enorme (untyped float constant 1e+100) as int64 value in variable declaration (truncated)
El compilador te protege antes de que el programa siquiera exista.
Lejos de debilitar el sistema de tipos estático, las constantes sin tipo lo refuerzan: dan flexibilidad donde es segura (en compilación) y obligan a ser explícito donde la semántica importa.
Cuando usar constantes tipadas
Las constantes tipadas deben usarse cuando el tipo forma parte del significado o quieres comunicar intención:
const (
MaxWorkers int = 100 // límite razonable de workers
DefaultTimeout int64 = 30 // segundos, no milisegundos
BufferSize uint32 = 65536 // bytes, tamaño de buffer de red
Version string = "v2.3.1" // tipo string explícito por claridad
)
En estos casos el tipo documenta la constante y reduce el riesgo de usarla en un contexto equivocado.
Conclusión
Las constantes sin tipo y las constantes tipadas no son un detalle técnico oscuro: son una de las decisiones más elegantes del diseño de Go.
Combinan la flexibilidad casi dinámica para valores genéricos y matemáticos (sin sacrificar seguridad), y la rigurosidad estática cuando la claridad semántica y el control de tipos importan.
Entender bien esta dualidad es un paso importante para escribir código Go idiomático, limpio y que comunica intención con fuerza.
¿Has aprendido algo leyendo este artículo? Únete al canal de Telegram del blog, y pregúntame cualquier duda que te quede pendiente. Allí respondo personalmente a cada pregunta planteada.
¡Nos vemos en el próximo artículo!
Pulso la tecla ESC:wq!
Use the share button below if you liked it.
There's not much you can do without a CPU.