← Volver al listado de tecnologías
Tipos y Variables en Zig
Tipos y Variables
Variables y Constantes
En Zig, las variables se declaran con var y las constantes con const:
const std = @import("std");
pub fn main() void {
// Constante - no puede cambiar
const pi: f64 = 3.14159;
// Variable - puede cambiar
var contador: i32 = 0;
contador += 1;
// Inferencia de tipos
const mensaje = "Hola"; // tipo: *const [4:0]u8
var numero = @as(i32, 42); // tipo: i32
std.debug.print("Pi: {d}, Contador: {d}\n", .{ pi, contador });
}
Tipos Enteros
Zig ofrece control preciso sobre el tamaño de enteros:
| Tipo | Bits | Rango |
|---|---|---|
| i8 | 8 | -128 a 127 |
| u8 | 8 | 0 a 255 |
| i16 | 16 | -32,768 a 32,767 |
| u16 | 16 | 0 a 65,535 |
| i32 | 32 | -2^31 a 2^31-1 |
| u32 | 32 | 0 a 2^32-1 |
| i64 | 64 | -2^63 a 2^63-1 |
| u64 | 64 | 0 a 2^64-1 |
| isize | arch | Puntero con signo |
| usize | arch | Puntero sin signo |
const byte: u8 = 255;
const entero: i32 = -42;
const grande: u64 = 18_446_744_073_709_551_615;
const tamanio: usize = @sizeOf(i32); // 4
Tipos Flotantes
const f16_val: f16 = 1.5; // Media precisión
const f32_val: f32 = 3.14; // Precisión simple
const f64_val: f64 = 2.718; // Doble precisión
const f128_val: f128 = 1.0; // Precisión cuádruple
Booleanos
const verdadero: bool = true;
const falso: bool = false;
// Operaciones lógicas
const y = verdadero and falso; // false
const o = verdadero or falso; // true
const no = !verdadero; // false
Caracteres y Strings
// Carácter (u8)
const letra: u8 = 'A';
const unicode: u21 = '中';
// String literal (puntero a array de bytes)
const saludo: []const u8 = "Hola mundo";
// String con terminador null (para interop con C)
const c_string: [*:0]const u8 = "Hola C";
Optional Types
Los optionals pueden contener un valor o null:
const std = @import("std");
fn encontrar(haystack: []const u8, needle: u8) ?usize {
for (haystack, 0..) |char, index| {
if (char == needle) return index;
}
return null;
}
pub fn main() void {
const texto = "Hola";
// Usando optional
if (encontrar(texto, 'o')) |indice| {
std.debug.print("Encontrado en: {d}\n", .{indice});
} else {
std.debug.print("No encontrado\n", .{});
}
// Valor por defecto con orelse
const pos = encontrar(texto, 'x') orelse 999;
std.debug.print("Posición: {d}\n", .{pos});
}
Undefined y Null
// undefined - valor no inicializado (úsalo con cuidado)
var buffer: [100]u8 = undefined;
// null - para tipos optional
var opcional: ?i32 = null;
opcional = 42;
Coerción de Tipos
const std = @import("std");
pub fn main() void {
// Cast explícito con @as
const a: i32 = 10;
const b: i64 = @as(i64, a);
// @intCast para enteros
const c: u8 = @intCast(a);
// @floatFromInt para int a float
const d: f32 = @floatFromInt(a);
// @intFromFloat para float a int
const e: f64 = 3.7;
const f: i32 = @intFromFloat(e); // 3
std.debug.print("b={d}, c={d}, d={d}, f={d}\n", .{ b, c, d, f });
}
Testing de Tipos
const std = @import("std");
const testing = std.testing;
fn duplicar(n: i32) i32 {
return n * 2;
}
fn dividir(a: f64, b: f64) ?f64 {
if (b == 0) return null;
return a / b;
}
test "duplicar enteros" {
try testing.expectEqual(@as(i32, 10), duplicar(5));
try testing.expectEqual(@as(i32, -4), duplicar(-2));
try testing.expectEqual(@as(i32, 0), duplicar(0));
}
test "división con optional" {
// División normal
const resultado = dividir(10.0, 2.0);
try testing.expect(resultado != null);
try testing.expectEqual(@as(f64, 5.0), resultado.?);
// División por cero
const div_cero = dividir(10.0, 0.0);
try testing.expect(div_cero == null);
}
test "coerción de tipos" {
const entero: i32 = 100;
const flotante: f64 = @floatFromInt(entero);
try testing.expectEqual(@as(f64, 100.0), flotante);
}
test "tamaño de tipos" {
try testing.expectEqual(@as(usize, 1), @sizeOf(u8));
try testing.expectEqual(@as(usize, 4), @sizeOf(i32));
try testing.expectEqual(@as(usize, 8), @sizeOf(f64));
}
test "valores límite" {
const max_u8: u8 = std.math.maxInt(u8);
const min_i8: i8 = std.math.minInt(i8);
try testing.expectEqual(@as(u8, 255), max_u8);
try testing.expectEqual(@as(i8, -128), min_i8);
}
Ejecuta los tests:
zig test 02-tipos-variables.zig
# All 5 tests passed.
Comptime Types
Zig permite tipos determinados en tiempo de compilación:
fn crearArray(comptime T: type, comptime size: usize) [size]T {
return [_]T{0} ** size;
}
test "comptime array" {
const arr = crearArray(i32, 5);
try std.testing.expectEqual(@as(usize, 5), arr.len);
}
Ejercicios
- Crea una función que convierta temperatura de Celsius a Fahrenheit
- Implementa una función que encuentre el máximo entre dos números con tests
- Crea un tipo optional que represente un resultado de búsqueda
Resumen
constpara constantes,varpara variables mutables- Zig tiene tipos enteros de tamaño fijo (i8, u32, etc.)
- Los optionals (
?T) manejan valores que pueden ser null @as,@intCast,@floatFromIntpara conversiones de tipos- Los tests verifican comportamiento con
std.testing