← Volver al listado de tecnologías
Control de Flujo en Zig
Control de Flujo
Condicionales (if)
const std = @import("std");
pub fn main() void {
const numero = 42;
// If básico
if (numero > 0) {
std.debug.print("Positivo\n", .{});
} else if (numero < 0) {
std.debug.print("Negativo\n", .{});
} else {
std.debug.print("Cero\n", .{});
}
// If como expresión
const signo: i32 = if (numero >= 0) 1 else -1;
std.debug.print("Signo: {d}\n", .{signo});
}
If con Optionals
fn buscar(arr: []const i32, valor: i32) ?usize {
for (arr, 0..) |elem, i| {
if (elem == valor) return i;
}
return null;
}
pub fn main() void {
const numeros = [_]i32{ 1, 2, 3, 4, 5 };
// Captura del valor optional
if (buscar(&numeros, 3)) |indice| {
std.debug.print("Encontrado en índice: {d}\n", .{indice});
} else {
std.debug.print("No encontrado\n", .{});
}
}
Bucle While
const std = @import("std");
pub fn main() void {
// While básico
var i: u32 = 0;
while (i < 5) {
std.debug.print("{d} ", .{i});
i += 1;
}
// Output: 0 1 2 3 4
// While con continue expression
var j: u32 = 0;
while (j < 10) : (j += 1) {
if (j % 2 == 0) continue;
std.debug.print("{d} ", .{j});
}
// Output: 1 3 5 7 9
// While con else
var k: u32 = 0;
const resultado = while (k < 5) : (k += 1) {
if (k == 3) break k * 10;
} else @as(u32, 0);
std.debug.print("\nResultado: {d}\n", .{resultado}); // 30
}
Bucle For
const std = @import("std");
pub fn main() void {
const numeros = [_]i32{ 10, 20, 30, 40, 50 };
// For básico
for (numeros) |num| {
std.debug.print("{d} ", .{num});
}
// For con índice
for (numeros, 0..) |num, i| {
std.debug.print("\n[{d}] = {d}", .{ i, num });
}
// Iterar sobre rangos
for (0..5) |i| {
std.debug.print("{d} ", .{i});
}
// For sobre strings
const texto = "Hola";
for (texto) |char| {
std.debug.print("{c} ", .{char});
}
}
Switch
const std = @import("std");
const Color = enum { rojo, verde, azul, otro };
fn nombreColor(c: Color) []const u8 {
return switch (c) {
.rojo => "Rojo",
.verde => "Verde",
.azul => "Azul",
.otro => "Desconocido",
};
}
fn clasificarNumero(n: i32) []const u8 {
return switch (n) {
0 => "cero",
1, 2, 3 => "bajo",
4...10 => "medio",
else => "alto",
};
}
pub fn main() void {
std.debug.print("Color: {s}\n", .{nombreColor(.verde)});
std.debug.print("5 es: {s}\n", .{clasificarNumero(5)});
std.debug.print("100 es: {s}\n", .{clasificarNumero(100)});
}
Switch con Capturas
const std = @import("std");
const Operacion = union(enum) {
sumar: i32,
multiplicar: i32,
reset,
};
fn aplicar(valor: i32, op: Operacion) i32 {
return switch (op) {
.sumar => |n| valor + n,
.multiplicar => |n| valor * n,
.reset => 0,
};
}
test "operaciones con switch" {
var valor: i32 = 10;
valor = aplicar(valor, .{ .sumar = 5 });
try std.testing.expectEqual(@as(i32, 15), valor);
valor = aplicar(valor, .{ .multiplicar = 2 });
try std.testing.expectEqual(@as(i32, 30), valor);
valor = aplicar(valor, .reset);
try std.testing.expectEqual(@as(i32, 0), valor);
}
Break y Continue con Labels
const std = @import("std");
pub fn main() void {
// Break con label
const resultado = outer: for (0..10) |i| {
for (0..10) |j| {
if (i * j > 50) break :outer i * j;
}
} else @as(usize, 0);
std.debug.print("Resultado: {d}\n", .{resultado});
}
fn buscarEnMatriz(matriz: []const []const i32, objetivo: i32) ?struct { fila: usize, col: usize } {
for (matriz, 0..) |fila, i| {
for (fila, 0..) |valor, j| {
if (valor == objetivo) {
return .{ .fila = i, .col = j };
}
}
}
return null;
}
Testing de Control de Flujo
const std = @import("std");
const testing = std.testing;
fn esPositivo(n: i32) bool {
return if (n > 0) true else false;
}
fn factorial(n: u32) u32 {
var resultado: u32 = 1;
var i: u32 = 1;
while (i <= n) : (i += 1) {
resultado *= i;
}
return resultado;
}
fn sumarArray(arr: []const i32) i32 {
var suma: i32 = 0;
for (arr) |num| {
suma += num;
}
return suma;
}
fn clasificar(n: i32) []const u8 {
return switch (n) {
std.math.minInt(i32)...-1 => "negativo",
0 => "cero",
1...std.math.maxInt(i32) => "positivo",
};
}
test "condicionales" {
try testing.expect(esPositivo(5));
try testing.expect(!esPositivo(-3));
try testing.expect(!esPositivo(0));
}
test "factorial con while" {
try testing.expectEqual(@as(u32, 1), factorial(0));
try testing.expectEqual(@as(u32, 1), factorial(1));
try testing.expectEqual(@as(u32, 120), factorial(5));
try testing.expectEqual(@as(u32, 3628800), factorial(10));
}
test "suma con for" {
const arr1 = [_]i32{ 1, 2, 3, 4, 5 };
try testing.expectEqual(@as(i32, 15), sumarArray(&arr1));
const arr2 = [_]i32{ -1, 1 };
try testing.expectEqual(@as(i32, 0), sumarArray(&arr2));
const vacio = [_]i32{};
try testing.expectEqual(@as(i32, 0), sumarArray(&vacio));
}
test "switch clasificación" {
try testing.expectEqualStrings("negativo", clasificar(-100));
try testing.expectEqualStrings("cero", clasificar(0));
try testing.expectEqualStrings("positivo", clasificar(42));
}
test "for con índice" {
const datos = [_]i32{ 10, 20, 30 };
var suma_indices: usize = 0;
var suma_valores: i32 = 0;
for (datos, 0..) |val, idx| {
suma_indices += idx;
suma_valores += val;
}
try testing.expectEqual(@as(usize, 3), suma_indices); // 0+1+2
try testing.expectEqual(@as(i32, 60), suma_valores); // 10+20+30
}
test "while con break" {
var contador: u32 = 0;
const resultado = while (contador < 100) : (contador += 1) {
if (contador == 7) break contador;
} else @as(u32, 999);
try testing.expectEqual(@as(u32, 7), resultado);
}
Ejercicios
- Implementa FizzBuzz usando control de flujo
- Crea una función que encuentre el número más grande en un array
- Implementa búsqueda binaria con while
Resumen
ifpuede usarse como expresión para retornar valoreswhilesoporta continue expressions y else branchforitera sobre arrays, slices y rangosswitches exhaustivo y soporta rangos y múltiples valores- Labels permiten break/continue en bucles anidados