Hey y’all,
I have been messing around with some more complex formatting, in this case for matrices. After reading through some threads here and working with the std.testing.allocator
, I have arrived at the following example for a memory-leak free formatting function that accepts runtime values. The issue is that what I came up with feels ugly.
What are some examples you’ve come across that showcase idiomatic complex formatting in Zig?
What I came up with and some notes:
clearAndFree()
is necessary to prevent the output from persisting between formatting callsdefer alloc.free(s)
appear to be necessary for freeing the allocated memory from thestd.fmt.allocPrint
function (and prevent a memory leak).
pub fn format(mat: *Matrix, alloc: std.mem.Allocator, out: *std.ArrayList(u8)) ![]const u8 {
const label = @typeName(Matrix)[0..];
try out.appendSlice(label);
try out.appendSlice("[\n"[0..]);
for (0..rows) |ridx| {
try out.appendSlice("\t["[0..]);
for (0..cols) |cidx| {
const s = try std.fmt.allocPrint(alloc, "{any}", .{mat.get(ridx, cidx)});
defer alloc.free(s);
try out.appendSlice(s);
if (cidx != cols - 1) {
try out.append(',');
}
}
try out.append(']');
if (ridx != rows - 1) {
try out.appendSlice(",\n"[0..]);
}
}
try out.appendSlice("]\n");
return out.items;
} // ... rest of the struct
// invocation in a test block...
var alloc = std.testing.allocator;
const arrayListString = std.ArrayList(u8);
var out = arrayListString.init(alloc);
defer out.deinit();
std.debug.print("\nlower: {s}\n", .{try lower.format(alloc, &out)});
out.clearAndFree();
std.debug.print("\nupper: {s}\n", .{try upper.format(alloc, &out)});
out.clearAndFree();