Cómo usar variables, const y el iota en Go para crear constantes enumeradas Go

Cómo usar variables, const y el iota en Go para crear constantes enumeradas

DUGLAS MORENODUGLAS MORENO 👁 10

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:

  1. Declarar variables y constantes con los distintos alcances que ofrece Go.
  2. Utilizar iota para crear listas de constantes numeradas sin errores manuales.
  3. 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.14159

Inferencia 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 escritura

Buenas 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 Stringer para que tus constantes tengan una representación legible en logs.
  • Explorá paquetes externos como golang.org/x/tools/go/ast/astutil si 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.

Comentarios (0)

Sé el primero en comentar.

Dejá tu comentario