Interfaces and Polymorphism Patterns
Zig has no built-in interfaces, so it uses explicit patterns.
27.1 Compile-Time Polymorphism (anytype / Duck Typing)
fn drawAll(shapes: anytype) void {
inline for (shapes) |s| s.draw(); // any type with a draw() method
}27.2 Tagged Union Dispatch (Closed Set)
Fast (no indirection), exhaustive, and cache-friendly. Best when the set of types is known.
const Shape = union(enum) {
circle: Circle,
square: Square,
pub fn area(self: Shape) f32 {
return switch (self) {
inline else => |s| s.area(), // forwards to each variant's method
};
}
};27.3 Runtime Interface: VTable / Fat Pointer (Open Set)
This is exactly how std.mem.Allocator and std.Io.Writer work.
const Writer = struct {
ptr: *anyopaque,
vtable: *const VTable,
const VTable = struct {
write: *const fn (ptr: *anyopaque, bytes: []const u8) anyerror!usize,
};
pub fn write(self: Writer, bytes: []const u8) !usize {
return self.vtable.write(self.ptr, bytes);
}
};
const ConsoleSink = struct {
count: usize = 0,
fn writeImpl(ptr: *anyopaque, bytes: []const u8) anyerror!usize {
const self: *ConsoleSink = @ptrCast(@alignCast(ptr));
self.count += bytes.len;
std.debug.print("{s}", .{bytes});
return bytes.len;
}
pub fn writer(self: *ConsoleSink) Writer {
return .{ .ptr = self, .vtable = &.{ .write = writeImpl } };
}
};27.4 @fieldParentPtr Interfaces (Embedded Interface)
std.Io.Writer in 0.15 uses a similar "interface embedded in the implementation" design with the buffer inside the interface.
const Animal = struct {
speakFn: *const fn (*Animal) void,
pub fn speak(self: *Animal) void { self.speakFn(self); }
};
const Dog = struct {
animal: Animal = .{ .speakFn = speak },
name: []const u8,
fn speak(a: *Animal) void {
const self: *Dog = @fieldParentPtr("animal", a);
std.debug.print("{s}: woof\n", .{self.name});
}
};27.5 Choosing a Pattern
Max performance, types known at compile time anytype / comptime generics Closed set of variants Tagged union + inline else
Open set, runtime plugins, heterogeneous collections VTable fat pointer
Intrusive structures, implementations embedding the interface