Cómo usar variables, const y el iota en Go para crear constantes enumeradas
Introducción
Go es un lenguaje que, a diferencia de otros como JavaScript o Python, distingue de forma clara entre variables y constantes. Entender cuándo usar cada una y, sobre todo, cómo aprovechar el mecanismo de iota para generar conjuntos de constantes enumeradas, es fundamental para escribir código limpio, mantenible y libre de errores.
Este artículo está dirigido a desarrolladores que ya tienen nociones básicas de Go y quieren profundizar en la gestión de valores inmutables y la generación automática de enumeraciones. Al final vas a poder:
- Declarar variables y constantes con los distintos alcances que ofrece Go.
- Utilizar
iotapara crear listas de constantes numeradas sin errores manuales. - Aplicar buenas prácticas para evitar trampas comunes al trabajar con enumeraciones.
Variables y constantes en Go
Declaración básica
En Go, la palabra clave var se usa para crear variables cuyo valor puede cambiar a lo largo de la ejecución. Por otro lado, const define constantes cuyo valor es inmutable después de la compilación.
// Variable mutable
var contador int = 10
// Constante inmutable
const Pi float64 = 3.14159Inferencia de tipos
Go permite omitir el tipo si el compilador puede inferirlo a partir del valor asignado. Esto funciona tanto para var como para const.
var nombre = "Golang"
const mensaje = "Hola Mundo"Alcance y visibilidad
- Package level: Si declarás una variable o constante fuera de cualquier función, será visible para todo el paquete. Si su identificador comienza con mayúscula, será exportado y visible fuera del paquete.
- Function level: Dentro de una función, la variable o constante solo existirá en ese bloque.
package main
var Global = 42 // Exportada
func main() {
var local = "solo aquí"
_ = local // evitar warning de variable no usada
}El poder de iota
Qué es iota
iota es un predeclared identifier que Go inicializa a 0 y que se incrementa automáticamente en cada línea de una declaración const del mismo bloque. Sirve para generar series de valores numéricos sin escribirlos a mano.
Uso básico
package main
import "fmt"
const (
Sun = iota // 0
Moon // 1
Star // 2
)
func main() {
fmt.Println(Sun, Moon, Star) // salida: 0 1 2
}Salida esperada: 0 1 2
Saltos y asignaciones explícitas
Puedes combinar iota con valores explícitos y reiniciar la cuenta con una nueva declaración const.
package main
import "fmt"
const (
// Días de la semana, empezando en 1
Monday = iota + 1 // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
Sunday // 7
)
func main() {
fmt.Println("Viernes es el día", Friday) // salida: Viernes es el día 5
}Uso avanzado: máscaras de bits
iota es particularmente útil para crear flags que representan bits individuales. Cada constante será una potencia de dos, lo que permite combinarlas con operadores bitwise.
package main
import "fmt"
const (
FlagRead = 1 << iota // 1 << 0 => 1
FlagWrite // 1 << 1 => 2
FlagExecute // 1 << 2 => 4
)
func main() {
// Combinar permisos de lectura y ejecución
perms := FlagRead | FlagExecute
fmt.Printf("perms = %b
", perms) // salida: perms = 101
// Verificar si tiene permiso de escritura
if perms&FlagWrite != 0 {
fmt.Println("Tiene permiso de escritura")
} else {
fmt.Println("No tiene permiso de escritura") // se ejecuta
}
}Salida esperada:
perms = 101
No tiene permiso de escrituraBuenas prácticas y errores comunes
1. No mezclar tipos en una lista iota
iota siempre genera valores del tipo int (o el tipo que hayas asignado a la constante). Mezclarlo con float64 u otros tipos en la misma declaración producirá un error de compilación.
// Incorrecto
const (
a = iota // int
b = 3.14 // float64 → error
)2. Evitar valores implícitos cuando la enumeración es pública
Si exportás una enumeración, es buena práctica asignar valores explícitos a los primeros elementos para que futuros cambios no rompan la compatibilidad.
// Buena práctica
const (
StatusOK = 200
StatusError = iota + 201 // 201, 202, …
)3. No olvidar el reset de iota
Cada nuevo bloque const reinicia iota a 0. Si necesitás continuar una serie, deberás usar una única declaración o calcular el offset manualmente.
const (
A = iota // 0
B // 1
)
const (
C = iota + 2 // 2 (iota reinicia en 0)
D // 3
)4. No usar iota para valores que pueden cambiar en tiempo de ejecución
Recuerda que iota es una constante en tiempo de compilación. Si necesitás generar valores dinámicos, usá variables o funciones.
5. Documentar enumeraciones
Siempre acompañá tus bloques const con comentarios que expliquen el significado de cada valor. Facilita el mantenimiento y la generación de documentación automática.
// Nivel de log para la aplicación
const (
LogDebug = iota // 0 – mensajes de depuración
LogInfo // 1 – información general
LogWarn // 2 – advertencias
LogError // 3 – errores críticos
)Conclusión
En Go, la distinción entre variables y constantes es clara y poderosa. Las constantes, combinadas con el ingenioso iota, permiten crear enumeraciones seguras, legibles y libres de errores manuales. Aprovechá iota para listas secuenciales, offsets personalizados y máscaras de bits, pero recordá sus limitaciones: solo funciona en tiempo de compilación y siempre genera valores del mismo tipo.
Próximos pasos
- Refactorizá tus códigos heredados para sustituir valores mágicos por enumeraciones con
iota. - Implementá interfaces
Stringerpara que tus constantes tengan una representación legible en logs. - Explorá paquetes externos como
golang.org/x/tools/go/ast/astutilsi necesitás generar código con enumeraciones automáticamente.
Con esta base, estarás listo para escribir código Go más robusto y expresivo, reduciendo bugs y mejorando la mantenibilidad de tus proyectos.
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.