Zig es un lenguaje de programación de sistemas diseñado para ser robusto, rápido y fácil de aprender.
Ofrece manejo manual de la memoria, control de bajo nivel, y es una excelente opción para quienes buscan desarrollar sistemas y software de alto rendimiento.
Instalación
Instalar Zig en Linux
sudo apt install zig
Instalar Zig en Windows
- Descarga la última versión de Zig desde el sitio oficial.
- Extrae el archivo ZIP y agrega el directorio a la variable de entorno
PATH
.
Verificar la instalación
Para verificar que Zig está instalado correctamente, ejecuta:
zig version
Introducción
Compilación Básica
Para compilar un archivo Zig
zig build-exe archivo.zig
Ejecución directa
Para ejecutar directamente
zig run archivo.zig
Estructura básica de un programa Zig
const std = @import("std");
pub fn main() void {
const stdout = std.io.getStdOut().writer();
stdout.print("Hello, Zig!\n", .{}) catch {};
}
Tipos de Datos en Zig
Zig tiene tipos de datos simples, como enteros, flotantes y punteros, así como tipos compuestos como estructuras y arrays.
Enteros
i8
,i16
,i32
,i64
: Enteros con signo.u8
,u16
,u32
,u64
: Enteros sin signo.
var a: i32 = 42;
var b: u64 = 100;
Flotantes
f16
,f32
,f64
: Números de punto flotante.
var pi: f32 = 3.14159;
Booleanos
bool
: Puede sertrue
ofalse
.
var is_open: bool = true;
Cadenas
- Las cadenas son arrays de caracteres (
[]const u8
).
const greeting: []const u8 = "Hello, Zig!";
Variables y Constantes
Variables
Se declaran con var
. Pueden cambiar su valor.
const pi: f32 = 3.14; // constante
var counter: i32 = 0; // variable
Constantes
Se declaran con const
. No pueden cambiar su valor.
const pi: f32 = 3.14; // constante
var counter: i32 = 0; // variable
Operadores
Aritméticos
- Suma:
+
- Resta:
-
- Multiplicación:
*
- División:
/
- Módulo:
%
var x = 10 + 5; // 15
var y = 10 % 3; // 1
Comparación
- Igual:
==
- Diferente:
!=
- Mayor:
>
- Menor:
<
- Mayor o igual:
>=
- Menor o igual:
<=
if x == 10 {
// código
}
Control de Flujo
Condicionales
If - Else
if x > 10 {
// código si la condición es verdadera
} else {
// código si la condición es falsa
}
Switch
switch (x) {
1 => std.debug.print("Uno\n", .{}),
2 => std.debug.print("Dos\n", .{}),
else => std.debug.print("Otro número\n", .{}),
}
Bucles
For
for (i32(i = 0); i < 10; i += 1) {
std.debug.print("i: {}\n", .{i});
}
While
var i: i32 = 0;
while (i < 10) : (i += 1) {
// código que se ejecuta mientras i sea menor a 10
}
For en colecciones
const arr = [_]i32{1, 2, 3};
for (arr) |value| {
// value contiene los elementos del array
}
Funciones
Definición de Funciones
Zig permite definir funciones con argumentos y valores de retorno.
fn suma(a: i32, b: i32) i32 {
return a + b;
}
- El prefijo
pub
hace la función pública (visible desde otros archivos Zig). - Si no se devuelve nada, el tipo de retorno es
void
.
Llamada a Funciones
const resultado = suma(5, 3);
std.debug.print("Resultado: {}\n", .{resultado});
Funciones anónimas (lambdas)
const multiplicar = fn (a: i32, b: i32) i32 {
return a * b;
};
Funciones Inline
fn cuadrado(x: i32) i32 {
return x * x;
}
const resultado = cuadrado(5);
Funciones Genéricas
fn intercambiarGenerico(comportamiento: anytype, a: anytype, b: anytype) void {
var temp: anytype = a;
a = b;
b = temp;
}
Tipos compuestos
Arrays
Los arrays son tipos de longitud fija.
const numeros: [5]i32 = [5]i32{1, 2, 3, 4, 5};
Slices
const slice = &numeros[1..4]; // Accede a los elementos del índice 1 al 3
std.debug.print("Elementos en slice: {}\n", .{slice});
Estructuras
Las estructuras (structs
) son tipos de datos personalizados que pueden contener varios valores.
const Punto = struct {
x: i32,
y: i32,
};
const punto: Punto = Punto { .x = 10, .y = 20 };
Enumeraciones
Las enumeracionse (enum
) definen un conjunto de valores posibles para una variable.
const Estado = enum {
Inactivo,
Activo,
};
const estado: Estado = Estado.Activo;
Uniones
const Valor = union {
entero: i32,
decimal: f32,
};
var v: Valor = Valor{ .entero = 10 };
std.debug.print("Valor entero: {}\n", .{v.entero});
Manejo de Memoria
Punteros
Zig permite el manejo manual de punteros.
var x: i32 = 42;
var ptr: *i32 = &x;
Reserva de memoria de Memoria
const memoria = std.heap.page_allocator;
const ptr = try memoria.allocate(i32, 1);
ptr.* = 42;
defer memoria.deallocate(ptr);
Liberación de memoria
Zig no tiene un recolector de basura, por lo que la asignación y liberación de memoria se debe hacer manualmente.
var allocator = std.heap.page_allocator;
const buffer = try allocator.alloc(u8, 1024); // asignar 1024 bytes
defer allocator.free(buffer); // liberar memoria
Defer
defer
ejecuta una instrucción justo antes de que la función termine. Útil para liberar recursos.
const std = @import("std");
pub fn main() void {
var file = try std.fs.cwd().openFile("archivo.txt", .{});
defer file.close(); // se ejecuta justo antes de que termine la función
}
Manejo de Errores
Zig no utiliza excepciones. En su lugar emplea un sistema de manejo de errores, basado en el uso de try
, catch
, y códigos de error.
Errores explícitos
Las funciones pueden retornar errores que deben ser manejados.
fn division(a: i32, b: i32) !i32 {
if (b == 0) {
return error.DivisionPorCero;
}
return a / b;
}
Try - Catch
try
: Ejecuta una operación que puede fallar. Si falla, devuelve el error al llamador.catch
: Captura errores.
const archivo = try std.fs.cwd().openFile("archivo.txt", .{}).catch |err| {
std.debug.print("Fallo al abrir archivo: {}\n", .{err});
};
Asserts
const a: i32 = 5;
const b: i32 = 10;
assert(a < b, "a debe ser menor que b");
Concurrencia
Zig tiene soporte para tareas asíncronas usando async
y await
.
Definir funciones asíncronas
fn obtener_dato_async() async i32 {
return 42;
}
pub fn main() void {
const dato = await obtener_dato_async();
}
Módulos
Crear Módulos
Crea un archivo llamado mi_modulo.zig
.
pub fn funcionModulo() void {
std.debug.print("Función del módulo llamada\n", .{});
}
Importar Módulos
const std = @import("std");
const mi_modulo = @import("mi_modulo.zig");
pub fn main() void {
mi_modulo.funcionModulo();
}
Interoperabilidad con C
Zig permite importar y utilizar código en C directamente.
Importar C
const c = @cImport({
@cInclude("stdio.h");
});
pub fn main() void {
c.printf("Hola desde C!\n");
}
Zig también puede compilar archivos de C junto con Zig. Esto es útil para integrar bibliotecas C en proyectos Zig.