Variables y constantes

Crea un fichero llamado hello_user.zig con el siguiente contenido:

hello_user.zig

const std = @import("std");

pub fn main() void {

    std.debug.print("\nHola, usuario.\n", .{});

}

        ¿Te acuerdas que en el ejemplo anterior para escribir una línea de texto hicimos:

 @import("std").debug.print("¡Hola mundo!\n", .{});

Ese comando @import  importa la librería estándar de Zig en nuestro programa. En el primer ejemplo importamos y usamos la librería en la misma línea. En el segundo ejemplo importamos la librería en la primera línea del programa, fuera de la función main.

 const std = @import("std");

Y además, como ves, al importar la librería, en vez de usar inmediatamente debug.print, asignamos la librería a un identificador (nombre simbólico), en este caso std.

El identificador  podría ser diferente. Podríamos poner algo como:

 const my_fav_lib = @import("std");

Pero eso no tendría mucho sentido. La librería estándar se suele asignar al identificador std. Los identificadores que usamos para denominar las cosas deberían ser autoexplicativos.

El uso de la palabra reservada const, delante del identificador, implica que estamos declarando una constante.

Declarar una constante en Zig significa asignar un valor a un identificador (como std o my_fav_lib),  y que ese valor ya no se podrá cambiar mientras se ejecuta el programa.

        Por ejemplo, podemos asignar otro tipo de valores a las constantes:

  const n_a = 1;

En este caso estamos asignando al identificador n_a el valor 1 y ese valor ya no se puede cambiar durante la ejecución del programa.

Vamos a intentar cambiar la constante n_a al valor 2.

const.zig

const std = @import("std");

pub fn main() void {

    const n_a = 1;

    n_a = 2;

}

Si Intentamos ejecutar este programa veremos un error:

$ zig run constants.zig

constants.zig:6:5: error: cannot assign to constant

    n_a = 2;

    ^~~

El compilador de Zig nos avisa que no puede (re)asignar un valor a una constante.

Pero ¿y si queremos poder cambiar ese valor?

Es muy sencillo, lo único que tenemos que hacer es poner la palabra clave var en vez de const delante del identificador.

        Poner la palabra var delante del nombre simbólico quiere decir que estamos declarando una variable. El valor que contiene una variable puede ser cambiado  durante la ejecución del programa.

vars.zig

const std = @import("std");

pub fn main() void {

    var n_a = 1;

    n_a = 2;

}

Si intentamos ejecutar vars.zig veremos… ¡Un momento! El compilador tiene una objeción:

$ zig run vars.zig

vars.zig:4:9: error: variable of type 'comptime_int' must be const or comptime

    var n_a = 1;

        ^~~

vars:5:7: note: to modify this variable at runtime, it must be given an explicit fixed-size number type

¿Qué significa esto? El compilador necesita saber de forma clara qué tipo de datos va a almacenar la variable. No basta con poner var n_a = 1;, porque Zig aquí necesita saber exactamente qué tipo de número vamos a usar.

Ahora mismo, esto del tipo de dato y el tipo de número puede sonar un poco confuso. No pasa nada. En seguida vamos a ver qué significa todo esto de los tipos de datos en Zig, pero de momento vamos a añadir un tipo explícito a la variable para poder ejecutar el programa.

vars_2.zig

const std = @import("std");

pub fn main() void {

    var n_a: u8 = 1; // asignamos el tipo u8

    n_a = 2;

}

$ zig run vars_2.zig

No tenemos ninguna salida ya que no hemos impreso nada, pero tampoco hay ningún error. Esto quiere decir que hemos conseguido cambiar el valor de la variable n_a con éxito. Intenta jugar un poco con el playground de zenofzig.com con lo aprendido hasta ahora para imprimir esta variable.

Comprendemos que en Zig tenemos:

Se declaran usando la palabra const delante del identificador y NO pueden cambiar su valor durante la ejecución del programa.

Se declara con var y sí pueden cambiar su valor durante la ejecución del programa, pero necesitamos poner el tipo de dato (u8, i32 etc)

Cuando usar variables y cuando las constantes

Imagina que en un juego comienzas con 3 vidas. Eso es una regla fija - ideal para usar una constante. No cambia mientras se ejecuta el programa, y cada vez que se inicia una nueva partida volvemos a tener esas vidas iniciales. Así podríamos tener:

 const N_START_LIVES = 3;

        Sin embargo, las vidas actuales que nos quedan en la partida no son un número fijo: pueden ir desde 0 (si perdemos todas) hasta lo máximo que logremos sumar encontrando vidas extra. Esto claramente es una variable ya que va cambiando durante cada partida.

 var n_lives = N_START_LIVES;

lives.zig

const std = @import("std");

// vidas al inicio del juego

const N_START_LIVES: u8 = 3;

pub fn main() void {

    // vidas al inicio del juego

    var n_lives = N_START_LIVES;

    std.debug.print("Tienes {d} vidas\n", .{n_lives});

    std.debug.print("¡Oh no! Te acaban de matar.\n", .{});

    // el jugador pierde una vida

    n_lives -= 1;

    std.debug.print("Ahora tienes {d} vidas\n", .{n_lives});

    std.debug.print("Has encontrado una vida extra.\n", .{});

    // el jugador recoge una vida extra

    n_lives += 1;

    std.debug.print("Ahora tienes {d} vidas\n", .{n_lives});

}

$ zig run lives.zig

Tienes 3 vidas

¡Oh no! Te acaban de matar.

Ahora tienes 2 vidas

Has encontrado una vida extra.

Ahora tienes 3 vidas

Siguiendo este ejemplo hay que intentar usar:

Estructura de un programa
Comentarios
© 2025 Zen of Zig