Fundamentos de las Constantes en Go

GolangBeginner
Practicar Ahora

Introducción

En las lecciones anteriores, aprendimos sobre las variables en Go. En esta sesión, exploraremos el concepto de las constantes, cómo utilizarlas y por qué son fundamentales en el desarrollo de software. Sumerjámonos en el mundo de los valores inmutables.

Puntos de conocimiento:

  • Qué son las constantes
  • Declaración de constantes
  • El generador de constantes iota
  • Uso práctico de las constantes

¿Qué son las constantes?

En términos sencillos, una constante es un valor que se declara y no puede ser modificado durante la ejecución del programa. Las constantes permiten que el compilador conozca sus valores antes de que el programa se ejecute, específicamente durante la fase de compilación.

A las declaraciones de constantes se les pueden asignar valores específicos. Su sintaxis es muy similar a la de las variables, pero con una diferencia crucial: una vez que se declara el valor de una constante, este permanece inalterable.

Las constantes son extremadamente útiles cuando deseas definir un valor que no debe cambiar, como la dirección de un sitio web o un valor matemático específico como π (Pi).

Declaración de constantes

La declaración de constantes es similar a la de las variables, con la diferencia de que la palabra clave var se sustituye por la palabra clave const.

Nota: Las constantes deben recibir un valor obligatoriamente en el momento de su declaración.

En Go, todas las variables deben utilizarse después de ser definidas, pero las constantes son una excepción a esta regla. Aunque declares una constante y no la uses, el compilador no generará ningún error.

La sintaxis para declarar una constante es la siguiente:

const name [type] = value

Donde name es el nombre de la constante, type es el tipo de dato (que puede omitirse ya que Go puede inferirlo automáticamente) y value es el valor asignado.

Ten en cuenta que solo los siguientes tipos pueden utilizarse para declarar constantes:

  • Tipos enteros
  • Tipos de punto flotante
  • Tipos complejos
  • Tipos booleanos
  • Tipos de cadena (strings)

Veamos un ejemplo práctico. Crea un nuevo archivo llamado const.go en el directorio ~/project:

touch ~/project/const.go

Introduce el siguiente código en const.go:

package main

import "fmt"

// Declarar una única constante
const labex string = "LabEx" // especificando explícitamente el tipo como string
const labs = "LABS"    // el compilador lo infiere automáticamente como string

// Declarar múltiples constantes
const (
    hangzhou, chengdu = "HANGZHOU", "CHENGDU"
    monday, tuesday, wednesday = "MONDAY", "TUESDAY", "WEDNESDAY"
)

func main() {
    fmt.Printf("The type of labex is: %T, and its value is %s\n", labex, labex)
    fmt.Printf("The type of labs is: %T, and its value is %s\n", labs, labs)

    fmt.Println()

    fmt.Println(hangzhou, chengdu)
    fmt.Println(monday, tuesday, wednesday)
}

Ejecuta el programa con el siguiente comando:

go run ~/project/const.go

Tras la ejecución, verás la siguiente salida:

The type of labex is: string, and its value is LabEx
The type of labs is: string, and its value is LABS

HANGZHOU CHENGDU
MONDAY TUESDAY WEDNESDAY

En este ejemplo, demostramos cómo declarar constantes individuales y múltiples. Al declarar varias constantes a la vez, se recomienda utilizar paréntesis para mejorar la legibilidad.

Aunque en este programa solo usamos cadenas de texto, recuerda que las constantes pueden ser de otros tipos, como enteros o booleanos.

Un detalle importante al declarar múltiples constantes con paréntesis es que, si una constante no se inicializa, heredará el valor de la constante anterior.

Prueba este comportamiento modificando el código en const.go:

package main

import "fmt"

const (
    monday    = "MONDAY"
    tuesday   = "TUESDAY"
    wednesday = "WEDNESDAY"
    thursday
    friday
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}

Ejecuta de nuevo:

go run ~/project/const.go

La salida será:

MONDAY TUESDAY WEDNESDAY WEDNESDAY WEDNESDAY

Aquí, thursday y friday no tienen valores asignados explícitamente. Según las reglas de Go, cuando una constante no se inicializa:

  • thursday hereda el valor de wednesday.
  • friday también hereda el valor de wednesday.

Este comportamiento permite escribir código más conciso, pero requiere precaución para evitar resultados inesperados.

Si deseas que cada una tenga su propio valor, debes asignarlos explícitamente:

const (
    monday    = "MONDAY"
    tuesday   = "TUESDAY"
    wednesday = "WEDNESDAY"
    thursday  = "THURSDAY"
    friday    = "FRIDAY"
)

Esto producirá la salida esperada:

MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY

El generador de constantes iota

Además de declarar constantes una por una, podemos usar iota para declararlas en bloques de forma secuencial. Veamos un ejemplo. Escribe el siguiente código en el archivo const.go:

package main

import "fmt"

const (
    monday    = iota // el valor inicial es 0
    tuesday   = iota // se incrementa en 1 cada vez
    wednesday = iota
    thursday  = iota
    friday    = iota
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}

Ejecuta el código:

go run ~/project/const.go

La salida será:

0 1 2 3 4

Al usar iota, el valor comienza en 0 y se incrementa automáticamente en 1 para cada elemento posterior dentro del bloque const.

Una vez declarado el primer elemento con iota, no es necesario asignarlo en las constantes siguientes del mismo bloque. El siguiente código funciona exactamente igual:

package main

import "fmt"

const (
    monday    = iota // 0
    tuesday          // 1
    wednesday        // 2
    thursday         // 3
    friday           // 4
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}

¿Qué sucede si queremos omitir un valor específico? Podemos usar el guion bajo (_), que actúa como un identificador vacío. El siguiente código omite el valor correspondiente al miércoles:

package main

import "fmt"

const (
    monday  = iota // 0
    tuesday        // 1
    _
    thursday // 3
    friday   // 4
)

func main() {
    fmt.Println(monday, tuesday, thursday, friday)
}

Ejecuta el programa:

go run ~/project/const.go

Como puedes observar, la salida es:

0 1 3 4

El operador iota también puede utilizarse en operaciones aritméticas. Prueba el siguiente código en const.go:

package main

import "fmt"

const (
    a = iota     // 0
    b = iota * 3 // 1 * 3
    c = iota + 4 // 2 + 4
)

const (
    B  = 1 << (iota * 10) // equivale a 1 << (0 * 10)
    KB                    // 1024
    MB                    // 1048576
)

func main() {
    fmt.Println(a, b, c)
    fmt.Println(B, KB, MB)
}

Ejecuta el programa:

go run ~/project/const.go

La salida será:

0 3 6
1 1024 1048576

En el primer bloque de constantes, usamos iota para realizar cálculos aritméticos simples.

En el segundo bloque, combinamos iota con el operador de desplazamiento a la izquierda << para representar los valores de 1 KB y 1 MB en bytes. Por ejemplo, 1 KB es igual a 1024B, y 1 MB es 1024 * 1024, lo que resulta en 1048576B.

Desafío

Ahora vamos a reforzar lo aprendido. Crea un nuevo archivo llamado iota.go y utiliza iota y constantes para mostrar los valores de 1GB y 1TB expresados en bytes (B).

Requisitos:

  1. No escribas directamente los números resultantes. Debes usar iota para realizar la conversión.
  2. El archivo iota.go debe estar ubicado en el directorio ~/project.

Pista: Puedes tomar como referencia el código de la sección anterior sobre "iota".

El formato de salida requerido es el siguiente:

1GB is equal to 1073741824B
1TB is equal to 1099511627776B

Resumen

Repasemos los conceptos clave que hemos cubierto en esta lección:

  • Las constantes son inmutables; no pueden modificarse una vez declaradas.
  • Se definen utilizando la palabra clave const.
  • Es una buena práctica usar paréntesis al declarar múltiples constantes.
  • El generador iota facilita la creación de enumeraciones y series de valores.
  • iota es versátil y puede integrarse en operaciones aritméticas y de bits.

En esta lección, profundizamos en el uso de constantes y descubrimos el potencial de iota. Las cadenas, los enteros, los números de punto flotante y las constantes constituyen los tipos de datos fundamentales en Go.

✨ Revisar Solución y Practicar