Hello,
I’d like to know if it’s possible for a function to run automatically when opening an import program.
The reason, a data loading once.
i’m ??? I’m sorry, all I have to do is implement an init, and if it’s not programmed in my module, I refuse.
the use of dates… for example
You can have a top level comptime block that calls functions. However, it won’t be run unless you use the import, you can ofc discard the import to force it to run
Do you mean something akin to an init function in Go that automatically runs once (per the containing file) at runtime?
If so, then no. You can are pretty much either going to execute a comptime function, which will evaluate during the compilation process,.or at runtime, which will need to be called manually.
init in Go is used mostly initialize complex variables like maps which cannot be done inline. In Zig we have comptime blocks, so it’s perfectly okay to just use regular initializers.
Things like init in Go or constructors of static variables in C++ are examples of “life before main” which generally causes more trouble than it solves. Newer / better designed languages like Rust or Zig avoid this pitfall.
This saying, if you really want to collate module initializers to run at the start of main, a sketch of a rather cursed solution may look like this:
// util/init.zig
const InitFn = *const fn() void;
var initializers = std.BoundedArray(InitFn, 1024) = .init(0) catch unreachable;
/// Use this instead of regular @import().
pub fn import(comptime path: []const u8) type {
const mod = @import(path);
if (std.meta.hasDecl(mod, "init"))
if (!std.mem.indexOfScalar(InitFn, initializers.constSlice(), &mod.init))
initializers.append(&mod.init) catch unreachable;
return mod;
}
pub fn runInitializers() void {
for (initializers.constSlice()) |init| init();
}
// main.zig
pub fn main() void {
@import("util/init.zig").runInitializers();
// ... rest of main ...
}
Needless to say, this isn’t something you should do at home