3 ms·
I'm not usually in the "defending C++" camp, but when I see this: pub const File = struct { pub fn writer(self: *File, buffer: []u8) Writer{ ret
by wasmperson 1y ago
I'm not usually in the "defending C++" camp, but when I see this:
pub const File = struct {
pub fn writer(self: *File, buffer: []u8) Writer{
return .{
.file = self,
.interface = std.Io.Writer{
.buffer = buffer,
.vtable = .{.drain = Writer.drain},
}
};
}
pub const Writer = struct {
file: *File,
interface: std.Io.Writer,
// this has a bunch of other fields
fn drain(io_w: *Writer, data: []const []const u8, splat: usize) !usize {
const self: *Writer = @fieldParentPtr("interface", io_w);
// ....
}
}
}
...I can't help but think of this:
struct FileWriter: public Writer {
File *file;
// this has a bunch of other fields
FileWriter(File *self, span<char> buffer)
: Writer(buffer), file(self) {}
size_t drain(span<span<char const> const> data, size_t splat) override {
// ....
}
};
Writing code to build a vtable and having it implicitly run at compile time is pretty neat, though!
- varyous 1y agoThe zig std library often builds vtables for structs in an effort to minimize runtime cost for the typical non-virtual cases. I feel it leads to creating a lot of boilerplate to effectively have virtual functions. Worse, you have to study the zig code in a case by case basis to determine how to even use this ad-hoc virtual function scheme. Surely zig can introduce virtual function support in a more ergonomic way than this, as it's so widely used in real life code and extensively in zig's own std library.