Hello!
Let’s say I have this function, which has to log stuff into a file, and I use a buffer and a writer like this:
const trace_file = try cwd.createFile(init.io, trace_path, .{ .read = false });
var trace_writer = trace_file.writer(init.io, &trace_buffer);
const twriter = &trace_writer.interface;
doSmth(..., twriter);
fn doSmth(args: types, trace: *Io.Writer) {
try trace.writeAll("very important data");
}
Now, imagine this is costly, and I want to control at runtime if this file should be written or not. I can just pass an optional value and react accordingly:
doSmth(..., null);
fn doSmth(args: types, trace: ?*Io.Writer) {
if (trace) |writer| { try trace.writeAll("very important data"); }
}
But then I saw the std.Io.Writer.Discarding and I thought I could get rid of the annoying null check if I do this!
var twriter = std.Io.Writer.Discarding.init(&.{});
doSmth(..., &twriter);
fn doSmth(args: types, trace: *Io.Writer) {
try trace.writeAll("very important data");
}
If it’s a buffered writer it will write, and if it’s a Discarding (I suppose) Zig’s compiler will optimize this away.
But I coded that an I get the following error message:
src/main.zig:120:66: error: expected type '*Io.Writer', found '*Io.Writer.Discarding'
const results = try simulation.v1(arena, rng, config, users, &twriter);
^~~~~~~~
src/main.zig:120:66: note: pointer type child 'Io.Writer.Discarding' cannot cast into pointer type child 'Io.Writer'
/home/pau/.zvm/master/lib/std/Io/Writer.zig:2384:24: note: struct declared here
pub const Discarding = struct {
^~~~~~
/home/pau/.zvm/master/lib/std/Io/Writer.zig:1:1: note: struct declared here
const Writer = @This();
^~~~~
src/simulation.zig:44:82: note: parameter type declared here
pub fn v1(gpa: Allocator, rng: Random, simconf: SimConfig, users: []User, trace: *Io.Writer) !SimResults {
Am I doing something wrong? I assume so because this would be so perfect xd. If not, I could go back to the null or make this parameter a union maybe? regardless, that’s a little bit ugly.
Thank you ![]()