Librerías
Igual que las funciones definidas por nosotros mismos, todas las funciones que llamamos en Zig - incluidas las de la librería estándar - tienen sus declaraciones en el propio código fuente. Por ejemplo, la función print que tanto estamos usando…
Podemos encontrar su implementación en la ruta donde hayamos descargado Zig. en el subdirectorio std encontraremos el fichero debug.zig
En ese archivo encontraremos la definición de la función:
|
/// Print to stderr, silently returning on failure. /// ... pub fn print(comptime fmt: []const u8, args: anytype) void { //... |
Si quisiéramos modificar esa función -o cualquier otra-, incluso si detectamos un error o queremos crear nuestra propia versión, somos libres de hacerlo.
Como nuestras declaraciones del modelado de torres, río, etc. están creciendo, podemos escribirlas en un archivo propio, por ejemplo:
|
hydro.zig |
|
const std = @import("std"); // una torre con cazos oscilantes pub const HydroTower = struct { const N_EFFICIENCY_PER_METER: f32 = 0.91; n_efficiency_per_meter: ?f32, // opcional n_height: f32, pub fn lift_water( self: *const HydroTower, n_input: ?f32, ) struct { f32, f32 } { return .{ (n_input orelse 0) * std.math.pow( f32, self.n_efficiency_per_meter orelse HydroTower.N_EFFICIENCY_PER_METER, self.n_height, ), self.n_height, }; } // simulamos una altura de torre construida entre 3.5 y 5m pub fn get_height_btw(n_min: f32, n_max: f32) f32 { return round2(get_rand( n_min, n_max, )); } }; // caudal del río llevado hasta la torre pub const WaterFlow = struct { n_liters_per_second: f32, pub fn get_fps(self: *const WaterFlow) f32 { const n_min = self.n_liters_per_second * 0.90; return round2(get_rand( n_min, self.n_liters_per_second, )); } }; // función inline para redondear a 2 decimales pub inline fn round2(n_x: f32) f32 { return @floor(100 * n_x) / 100; } // función inline para obtener un núm random entre n_min y n_max inline fn get_rand(n_min: f32, n_max: f32) f32 { return std.Random.float(std.crypto.random, f32) * (n_max - n_min) + n_min; } |
Este archivo no será ejecutable por sí solo, pero contiene las funciones y estructuras que hemos declarado y pueden ser usadas por otros archivos Zig. Así como importamos print de std.debug, ahora de la misma manera podemos reutilizar nuestras propias funciones. De esta forma no tenemos que definir una y otra vez el mismo código haciendo que nuestros programas sean significativamente más cortos. Hemos modularizado el programa.
Para que una función o estructura declarada en una librería se pueda llamar desde fuera tenemos que escribir la palabra reservada pub delante de la declaración de la misma:
|
pub const WaterFlow = struct { |
o
|
pub inline fn round2(n_x: f32) f32 { |
Sin embargo esta función será inalcanzable desde fuera del archivo que la contiene:
|
inline fn get_rand(n_min: f32, n_max: f32) f32 { |
Importamos y usamos el módulo así:
|
const std = @import("std"); const std = @import("std"); const print = std.debug.print; const ArrayList = std.ArrayList; // importamos la librería hydro que hemos escrito const hydro = @import("./hydro.zig"); const WaterFlow = hydro.WaterFlow; const HydroTower = hydro.HydroTower; // si no hemos importado una función // de manera explícita // tendremos que llamarla usando el // prefijo de la librería hydro.round2(n_riverflow) |