Taking GenericWriter
as an example:
pub fn GenericWriter(
comptime Context: type,
comptime WriteError: type,
comptime writeFn: fn (context: Context, bytes: []const u8) WriteError!usize,
) type {...
Is it possible to have something like this:
pub fn GenericStuff(
comptime Context: type,
comptime WriteError: type,
comptime writeFn: fn (context: Context, bytes: []const u8),
comptime writeFnOptional: ?fn (context: Context, bytes: []const u8) WriteError!usize,
) type {
...
Meaning that the second function would be optional?
(I guess this is not correct way…)
So, what would be the correct way to achieve what I’m trying to do?
Sze
2
What are you trying to do?
using an optional should work
2 Likes
You are right, ?fn
does work.
I thought it would be too crazy to be true.
In case anyone has similar doubts, here’s a simple example of working code:
const std = @import("std");
pub fn fnCore(
comptime Context: type,
comptime action: fn (
context: Context,
value: u8,
) u8,
comptime actionOption: ?fn (
context: Context,
value: u8,
) ?u8,
) type {
return struct {
context: Context,
const Self = @This();
pub inline fn act(
self: Self,
value: u8,
) u8 {
return action(
self.context,
value,
);
}
pub inline fn actOpt(
self: Self,
value: u8,
) ?u8 {
if (actionOption != null) {
const a = actionOption.?;
return a(
self.context,
value,
);
} else {
return null;
}
}
};
}
pub const FnStuff = struct {
two: u8 = 2,
three: u8 = 3,
const Self = @This();
const FnCore = fnCore(
*Self,
calcDouble,
null,
// calcTriple,
);
pub fn calcDouble(
self: *Self,
val: u8,
) u8 {
return self.two * val;
}
pub fn calcTriple(
self: *Self,
val: u8,
) ?u8 {
return self.three * val;
}
pub fn calc(
self: *Self,
) FnCore {
return .{
.context = self,
};
}
};
pub fn main() !void {
var fn_stuff = FnStuff{};
const stdout_file = std.io.getStdOut().writer();
var bw = std.io.bufferedWriter(stdout_file);
const stdout = bw.writer();
const t2 = fn_stuff.calc().act(3);
const t3 = fn_stuff.calc().actOpt(3);
try stdout.print("2 * 3 = {d}\n", .{t2});
try stdout.print("3 * 3 = {?}\n", .{t3});
try bw.flush(); // don't forget to flush!
}
1 Like
Sze
4
These are shorter:
const a = actionOption orelse return null;
return a(self.context, value);
return if(actionOption) |a| a(self.context, value) else null;
4 Likes
My C background prevents me to accept that you can do such if
and orelse
statements
1 Like