I am wondering whether it is possible to automatically derive the deinit function from an input struct.
My main problem is figuring out how to reconstruct a struct from its type information. Is this even possible?
const BluePrint = struct {
x: HasADeinitMethod,
y: HasADeinitMethod,
z: DoesNotHaveADeinitMethod,
// methods...
};
const ProperType = derive_deinit(BluePrint); // The same as BluePrint but now also has a deinit method.
fn derive_deinit(comptime T: type) type {
return struct {
// Help: How to copy all the fields from T?
// This does _not_ work: error: expected function, found 'for'
inline for(std.meta.fields(T)) |field| {
field,
}
// Help: How to copy all the methods from T?
fn deinit(self: *@This()) void {
// Call the fields' deinit methods in reverse order of declaration
// I think I can imagine how this would be done.
}
};
}
This is great. But do you have any idea whether it is possible to get T’s fields into the new struct? I tried inline for (edited my post) but that does not seem to be allowed inside the struct body.
You can’t, and that’s by design. Baking the fields of some struct into another struct leads to a kind of inheritance, while Zig prefers composition.
You shouldn’t construct generic types “casually”, it is better to construct the proper type and then add some generic things to it, than to try to go the other way around, which is discouraged; and that is why it doesn’t really work well.
For example you can’t add declarations / functions to types constructed with @Type.
If you want you can do something like this to add the deinit method to the concrete type instead: