Previously, I came up with a programming pattern that combines static and dynamic dispatch in Zig. You can see it below.
Here is a simple interface example.
// A simple interface example
pub const Trait = struct {...}; // static
pub const Interface = struct{ // dynamic
vptr: *anyopaque,
vtable: struct{...},
};
pub fn Warpper(comptime Impl: type) type { // unified abstract
...
return struct{
...
};
}
For the use of interfaces, accept parameters through anytype:
pub fn callInterface(warpper_impl: anytype) void {...}
If it is possible to deconstruct generic functions, the parameters can be replaced with more descriptive Warpper(|Impl|):
pub fn callInterface(warpper: Warpper(|Impl|)) void {...}
In this mode, Warpper(Interface) serves as a dynamic dispatch interface, while other interfaces implemented directly through generic parameter passing can serve as static dispatch interfaces.