Arrays
En Zig declaramos un array de la siguiente manera:
const nombre: [longitud del array]tipo = .{ valores separados por comas};
o
const nombre = [_ o longitud] tipo{ valores separados por comas };
Un array es una secuencia contigua del mismo tipo de datos. Esa secuencia siempre tiene una longitud fija, que puede ser:
- inferida por Zig a partir de los elementos (ponemos _ en vez de la longitud), o
- declarada de manera explícita - poniendo el tamaño del array y el tipo
array.zig |
|
const std = @import("std"); const print = std.debug.print; pub fn main() void { // tamaño inferido por los datos y el tipo const a_numbers = [_]u8{ 1, 2, 3, 4, 5 }; // tamaño declarado de manera explícita const a_numbers2: [5]u8 = .{ 1, 2, 3, 4, 5 }; print("Longitud de a_numbers es: {}.\n", .{a_numbers.len}); print("a_numbers2 impreso es: {any}.\n", .{a_numbers2}); } |
|
$ zig run array.zig |
|
Longitud de a_numbers es: 5. a_numbers2 impreso es: { 1, 2, 3, 4, 5 }. |
Para mostrar un array hemos puesto el formato {any} en la cadena impresa.
Longitud de un array
Los arrays en Zig tienen una propiedad llamada .len (de length - longitud) que podemos acceder como en el ejemplo previo. Esta propiedad es un número entero sin signo. Si indagamos un poco más en esta propiedad comprenderemos un detalle importante:
array_size.zig |
|
const std = @import("std"); const print = std.debug.print; pub fn main() void { const a_numbers_1 = [_]u8{ 2, 18, 78, 1, 3 }; const a_numbers_2 = [_]u16{ 8, 5, 10, 6, 12 }; const n_len_1 = a_numbers_1.len; const n_len_2 = a_numbers_2.len; // comprobamos las longitudes de los arrays print("a_numbers_1.len = {} elementos \n", .{n_len_1}); print("a_numbers_2.len = {} elementos \n\n", .{n_len_2}); // comprobamos el tipo de los arrays print("a_numbers_1 type = {} \n", .{@TypeOf(a_numbers_1)}); print("a_numbers_2 type = {} \n\n", .{@TypeOf(a_numbers_2)}); // comprobamos el tamaño de un elemento print("a_numbers_1 tamaño de un elemento = {d} bytes\n", .{@sizeOf(@TypeOf(a_numbers_1[0]))}); print("a_numbers_2 tamaño de un elemento = {d} bytes\n\n", .{@sizeOf(@TypeOf(a_numbers_2[0]))}); // el tipo del dato de la longitud print("a_numbers_1.len type = {} \n", .{@TypeOf(n_len_1)}); print("a_numbers_2.len type = {} \n\n", .{@TypeOf(n_len_2)}); // el tamaño del dato de la longitud print("a_numbers_1.len = {} bytes \n", .{@sizeOf(@TypeOf(n_len_1))}); print("a_numbers_2.len = {} bytes.\n", .{@sizeOf(@TypeOf(n_len_2))}); } |
|
$ zig run array_size.zig |
|
a_numbers_1.len = 5 elementos a_numbers_2.len = 5 elementos a_numbers_1 type = [5]u8 a_numbers_2 type = [5]u16 a_numbers_1 tamaño de un elemento = 1 bytes a_numbers_2 tamaño de un elemento = 2 bytes a_numbers_1.len type = usize a_numbers_2.len type = usize a_numbers_1.len = 8 bytes a_numbers_2.len = 8 bytes. |
Hemos definido dos arrays: a_numbers_1 y a_numbers_1. Ambos arrays tienen el mismo número pero distinto tipo de elementos:
- uno contiene elementos de 8 bits (1 byte)
- el otro tiene elementos de 16 bits (2 bytes cada uno)
Cuando consultamos su .len nos da la longitud de número de elementos: 5. Estos dos arrays son iguales en términos de longitud no de bytes que ocupan en memoria. El número que devuelve .len tiene un tipo de dato especial: usize.
Zig reserva el tipo usize para:
- contar elementos en arrays y slices,
- Representación de tamaños de memoria,
- Moverse por posiciones de memoria / estructuras de datos
Además el tamaño del tipo usize depende del sistema:
- En sistemas de 32 bits usize equivale a u32
- En sistemas de 64 bits, a u64
Cómo saber el tipo y el tamaño de un valor
Para saber el tipo de un elemento o una estructura usamos la función interna de Zig, llamada @TypeOf. La @ por delante del nombre, significa que es una función builtin (parte integral del lenguaje), como en el caso de la función @import que usamos para importar la librería estándar std.
La función que estamos usando para saber el tamaño de un tipo es @sizeOf. Y atención, que esta función no opera sobre un valor sin más, sino sobre su tipo, que hemos conseguido previamente con @TypeOf. Por ejemplo si quisiéramos hacer la llamada así nos daría un error:
|
@sizeOf(a_numbers_1[0]) |
error: expected type 'type', found 'u8'
La función @sizeOf espera un type como argumento:
|
@sizeOf(@TypeOf(a_numbers_1[0])) |