anytype y T: type

anytype y T: type

En este ejemplo vemos cómo, en la declaración de la función load_ammo, usamos x_ammo: anytype:

  // cargar diferentes cantidades / tipos de munición

  fn load_ammo(self: *MachineGun, x_ammo: anytype) void {

Hacemos uso de genéricos porque queremos permitir que se pueda añadir un único proyectil o varios a la vez representados por un array.  

También, podríamos definir de manera explícita el tipo como T y usarlo así:

  fn load_ammo(self: *MachineGun, T: type, x_ammo: T) void {

Las limitaciónes de anytype son:

  const x_ammo: anytype; <- error de compilación

  pack_ammo(x_ammo: anytype) @TypeOf(x_ammo);

  load_ammo([5]Proyectile, a_ammo); // sabemos que es un array de 5

Dentro del cuerpo de la función es necesario comprobar el tipo de dato concreto que estamos recibiendo para poder operar correctamente. Para ello usamos la función @TypeOf - para obtener el tipo del valor y @typeInfo - para inspeccionar la estructura y saber si se trata de un array.

  // si es un array cargamos todos los elementos

  switch (@typeInfo(@TypeOf(x_ammo))) {

    .array => for (x_ammo) |o_bullet| load_single(self, o_bullet),

    else => load_single(self, x_ammo),

  }

@typeInfo devuelve un union std.builtin.Type. En el propio código fuente de Zig, en el fichero builtin.zig podemos encontrar este tipo:

  pub const Type = union(enum) {

    type: void,

    void: void,

    bool: void,

    noreturn: void,

    int: Int,

    float: Float,

    pointer: Pointer,

    array: Array,

    ...

En el capítulo 6 vimos que en un union solo un campo puede estar activo a la vez. Aquí detectamos si el campo activo es .array, iteramos sobre los datos que nos llegan y “cargamos” un proyectil por iteración.

Builtins de introspección
Funciones Anónimas y Encapsuladas
© 2025 Zen of Zig