I have a function in my struct (Map
) like this (simplyfied):
pub fn any(self: Self, comptime compare: fn(src: u8) bool) bool
{
// run through data and call compare until found.
}
and a compare function:
fn compare_something(src: u8) bool
{
return src > 128;
}
and the call of any
:
const result: bool = my_map.any(compare_something);
which works.
but is this the best / fastest way to execute it this way?
I believe we cannot insert a ‘closure’ like function in Zig, can we?
You can use a struct to put the function inline.
const result: bool = my_map.any(struct {
fn compare_something(src: u8) bool
{
return src > 128;
}
}.compare_something);
But it can’t ingest lexical scope variables into function scope.
If you want to use it, you will need to pass contextual variable.
For instance:
pub fn any(self: Self, context: anytype, comptime compare: fn(context: anytype, src: u8) bool) bool
{
// run through data and call compare until found.
}
I believe that you can remove the comptime
and the result will be the same.
Ok. Both are more complicated, so I will keep it for now with the little extra function.
Another approach (duck typing)
const MyMap = struct {
pub fn any(self: MyMap, comptime Context: type, context: Context) bool {
comptime {
// function spec
std.debug.assert(std.meta.hasFn(Context, "compare"));
std.debug.assert(@TypeOf(Context.compare) == fn (Context, u8) bool);
}
_ = self;
const v1 = 200;
return context.compare(v1);
}
};
const MyContext = struct {
flag: bool,
pub fn compare (self: MyContext, src: u8) bool {
return self.flag and (src > 128);
}
};
pub fn main() !void {
const m = MyMap{};
const ctx = MyContext{.flag = false};
const result = m.any(MyContext, ctx);
std.debug.print("result: {}\n", .{result});
}