Control de flujo con if en Zig
Las estructuras de control de flujo permiten alterar el orden de ejecución del código según ciertas condiciones. En Zig, estas estructuras son potentes y versátiles, ofreciendo características que otros lenguajes no tienen. Vamos a explorar cómo funcionan las expresiones if
y else
en Zig.
Sentencias if-else
En Zig, las sentencias if
aceptan valores de tipo bool
(es decir, true
o false
). A diferencia de lenguajes como C o JavaScript, no hay valores que se conviertan implícitamente a valores booleanos. Esto significa que expresiones como if (1)
o if ("")
que funcionan en otros lenguajes, no son válidas en Zig.
const expect = @import("std").testing.expect;
test "sentencia if" {
const condicion = true;
var resultado: u16 = 0;
if (condicion) {
resultado += 1;
} else {
resultado += 2;
}
try expect(resultado == 1);
}
If como expresión
Una característica interesante de Zig es que las sentencias if
también funcionan como expresiones. Esto significa que pueden devolver un valor que puede ser asignado a una variable. Esto elimina la necesidad de un operador ternario (como condicion ? a : b
en otros lenguajes).
test "if como expresión" {
const condicion = true;
var resultado: u16 = 0;
resultado += if (condicion) 1 else 2;
try expect(resultado == 1);
}
If con opcionales
Zig permite usar if
con valores opcionales (tipos que pueden ser null
). Cuando usas if
con un opcional, puedes capturar el valor no nulo dentro del bloque if
.
test "if con opcionales" {
const valor: ?u32 = 10;
if (valor) |v| {
try expect(v == 10);
} else {
unreachable; // No se ejecutará porque valor no es null
}
const valorNulo: ?u32 = null;
if (valorNulo) |_| {
unreachable; // No se ejecutará porque valorNulo es null
} else {
// Este bloque se ejecuta si el valor es null
try expect(true);
}
}
If con uniones de error
Otra característica poderosa de Zig es que permite usar if
con uniones de error. Una unión de error es un tipo que puede contener o un valor o un error.
test "if con uniones de error" {
const resultado: anyerror!u32 = 10;
if (resultado) |valor| {
try expect(valor == 10);
} else |err| {
// Este bloque se ejecuta si el resultado es un error
_ = err;
unreachable;
}
}
Bloques else if
Como en otros lenguajes, puedes anidar bloques if
o usar else if
para evaluar múltiples condiciones.
test "cadenas de else if" {
const numero: i32 = 50;
var resultado: i32 = -1;
if (numero < 0) {
resultado = -1;
} else if (numero < 10) {
resultado = 1;
} else if (numero < 100) {
resultado = 2;
} else {
resultado = 3;
}
try expect(resultado == 2);
}
Acceso a valores por referencia
En Zig, puedes acceder a los valores capturados por referencia usando |*valor|
en lugar de |valor|
. Esto te permite modificar el valor dentro del bloque if
.
test "if con acceso por referencia" {
var valor: ?u32 = 10;
if (valor) |*v| {
v.* += 5;
}
try expect(valor.? == 15);
}
Combinar con otras características
La flexibilidad de Zig permite combinar las estructuras de control de flujo con otras características como comptime
para realizar operaciones en tiempo de compilación.
test "if en tiempo de compilación" {
comptime {
var resultado: u32 = 0;
if (true) {
resultado = 10;
}
try expect(resultado == 10);
}
}
La claridad y seguridad que ofrece Zig con sus estructuras de control de flujo ayuda a escribir código más robusto y menos propenso a errores. El hecho de que no haya conversiones implícitas a booleanos y que las sentencias if
puedan trabajar con opcionales y uniones de error de manera directa, facilita la escritura de código más claro y fácil de entender.