← Volver al listado de tecnologías
Arrays y Slices en Zig
Arrays y Slices
Arrays Estáticos
Los arrays tienen tamaño fijo conocido en tiempo de compilación:
const std = @import("std");
pub fn main() void {
// Array con tipo explícito
const numeros: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };
// Inferencia de tamaño
const letras = [_]u8{ 'a', 'b', 'c' };
// Array inicializado con valor
const ceros = [_]i32{0} ** 10; // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
// Acceso por índice
std.debug.print("Primero: {d}\n", .{numeros[0]});
std.debug.print("Longitud: {d}\n", .{numeros.len});
// Array de arrays (matriz)
const matriz = [3][3]i32{
[_]i32{ 1, 2, 3 },
[_]i32{ 4, 5, 6 },
[_]i32{ 7, 8, 9 },
};
std.debug.print("Centro: {d}\n", .{matriz[1][1]}); // 5
}
Slices
Los slices son vistas a arrays con longitud conocida en runtime:
const std = @import("std");
pub fn main() void {
var array = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Slice del array completo
const todo: []i32 = &array;
// Slice parcial [inicio..fin)
const medio = array[3..7]; // [4, 5, 6, 7]
// Desde el inicio
const primeros = array[0..3]; // [1, 2, 3]
// Hasta el final
const ultimos = array[7..]; // [8, 9, 10]
// Modificar a través del slice
todo[0] = 100;
std.debug.print("Primer elemento: {d}\n", .{array[0]}); // 100
// Longitud del slice
std.debug.print("Longitud medio: {d}\n", .{medio.len}); // 4
}
Strings
En Zig, los strings son arrays de bytes ([]const u8):
const std = @import("std");
pub fn main() void {
// String literal
const saludo: []const u8 = "Hola mundo";
// Longitud
std.debug.print("Longitud: {d}\n", .{saludo.len});
// Iterar caracteres
for (saludo) |char| {
std.debug.print("{c}", .{char});
}
// Comparación de strings
const a = "hola";
const b = "hola";
const iguales = std.mem.eql(u8, a, b);
std.debug.print("\nIguales: {}\n", .{iguales});
// String multilínea
const multi =
\\Línea 1
\\Línea 2
\\Línea 3
;
std.debug.print("{s}\n", .{multi});
}
Operaciones con Slices
const std = @import("std");
const mem = std.mem;
pub fn main() void {
const texto = "Hola,Mundo,Zig";
// Buscar substring
if (mem.indexOf(u8, texto, "Mundo")) |pos| {
std.debug.print("'Mundo' encontrado en: {d}\n", .{pos});
}
// Split
var iter = mem.splitSequence(u8, texto, ",");
while (iter.next()) |parte| {
std.debug.print("Parte: {s}\n", .{parte});
}
// Starts/ends with
std.debug.print("Empieza con 'Hola': {}\n", .{mem.startsWith(u8, texto, "Hola")});
std.debug.print("Termina con 'Zig': {}\n", .{mem.endsWith(u8, texto, "Zig")});
}
Sentinel-Terminated Arrays
Arrays terminados con un valor especial (útil para interop con C):
const std = @import("std");
pub fn main() void {
// String terminado en null (para C)
const c_string: [:0]const u8 = "Hola C";
// Longitud sin contar el terminador
std.debug.print("Longitud: {d}\n", .{c_string.len}); // 6
// Acceder al terminador
std.debug.print("Terminador: {d}\n", .{c_string[c_string.len]}); // 0
// Array terminado con valor custom
const arr: [5:255]u8 = [_:255]u8{ 1, 2, 3, 4, 5 };
std.debug.print("Sentinel: {d}\n", .{arr[5]}); // 255
}
Concatenación y Repetición
const std = @import("std");
pub fn main() void {
// Concatenación en comptime
const a = "Hola";
const b = " mundo";
const c = a ++ b; // "Hola mundo"
// Repetición
const repetido = "ab" ** 3; // "ababab"
std.debug.print("{s}\n", .{c});
std.debug.print("{s}\n", .{repetido});
}
Testing de Arrays y Slices
const std = @import("std");
const testing = std.testing;
const mem = std.mem;
fn sumar(arr: []const i32) i32 {
var total: i32 = 0;
for (arr) |n| total += n;
return total;
}
fn buscar(arr: []const i32, valor: i32) ?usize {
for (arr, 0..) |elem, i| {
if (elem == valor) return i;
}
return null;
}
fn invertir(arr: []i32) void {
var izq: usize = 0;
var der: usize = arr.len - 1;
while (izq < der) {
const temp = arr[izq];
arr[izq] = arr[der];
arr[der] = temp;
izq += 1;
der -= 1;
}
}
fn contiene(haystack: []const u8, needle: []const u8) bool {
return mem.indexOf(u8, haystack, needle) != null;
}
test "array básico" {
const arr = [_]i32{ 1, 2, 3, 4, 5 };
try testing.expectEqual(@as(usize, 5), arr.len);
try testing.expectEqual(@as(i32, 1), arr[0]);
try testing.expectEqual(@as(i32, 5), arr[4]);
}
test "slice de array" {
const arr = [_]i32{ 10, 20, 30, 40, 50 };
const slice = arr[1..4];
try testing.expectEqual(@as(usize, 3), slice.len);
try testing.expectEqual(@as(i32, 20), slice[0]);
try testing.expectEqual(@as(i32, 40), slice[2]);
}
test "suma de array" {
const arr = [_]i32{ 1, 2, 3, 4, 5 };
try testing.expectEqual(@as(i32, 15), sumar(&arr));
const vacio = [_]i32{};
try testing.expectEqual(@as(i32, 0), sumar(&vacio));
}
test "búsqueda en array" {
const arr = [_]i32{ 10, 20, 30, 40, 50 };
try testing.expectEqual(@as(?usize, 2), buscar(&arr, 30));
try testing.expectEqual(@as(?usize, 0), buscar(&arr, 10));
try testing.expectEqual(@as(?usize, null), buscar(&arr, 99));
}
test "invertir array" {
var arr = [_]i32{ 1, 2, 3, 4, 5 };
invertir(&arr);
try testing.expectEqual(@as(i32, 5), arr[0]);
try testing.expectEqual(@as(i32, 4), arr[1]);
try testing.expectEqual(@as(i32, 1), arr[4]);
}
test "comparación de strings" {
try testing.expect(mem.eql(u8, "hola", "hola"));
try testing.expect(!mem.eql(u8, "hola", "mundo"));
}
test "búsqueda en strings" {
const texto = "Zig es genial";
try testing.expect(contiene(texto, "es"));
try testing.expect(contiene(texto, "genial"));
try testing.expect(!contiene(texto, "malo"));
}
test "starts y ends with" {
const texto = "archivo.zig";
try testing.expect(mem.startsWith(u8, texto, "archivo"));
try testing.expect(mem.endsWith(u8, texto, ".zig"));
try testing.expect(!mem.startsWith(u8, texto, "otro"));
}
test "concatenación comptime" {
const resultado = "Hello" ++ " " ++ "World";
try testing.expectEqualStrings("Hello World", resultado);
}
Ejercicios
- Implementa una función que encuentre el elemento máximo de un array
- Crea una función que cuente las ocurrencias de un carácter en un string
- Implementa una función que verifique si un array es un palíndromo
Resumen
- Arrays tienen tamaño fijo:
[N]T - Slices son vistas dinámicas:
[]To[]const T - Strings son
[]const u8 std.memprovee funciones para manipular memoria- Sentinel arrays (
[:S]T) útiles para interop con C