Hello, I’m trying to embed a struct in another struct like in go or odin.
Something like this but in zig.
Foo :: struct {
x : i32
}
Baz :: struct {
using Foo
}
main :: proc() {
foo :: Foo{x = 10}
baz :: Baz{x = 10}
print_x(foo)
print_x(baz)
}
print_x :: proc(entity: Foo) {
fmt.println(entity.x)
}
I’m aware that there is no using keyword. However, When I search for issues in github i found this issue and according to this comment it’s doable with @Type builtin, but I couldn’t figure out how. Can anyone provide an example, please?
There used to be a usingnamespace keyword that allowed something similar to this. When it was removed there was some commentary in the release notes on suggested alternatives. Perhaps the “Mixin” category here would give some ideas on how to do this.
EDIT:
I forgot that the advice in the case of mixins was
The alternative for this is based on the key observation made above: namespacing is good, actually
So probably not what you are looking for. You can do some comptime meta-programming to take the fields from one type and add them on to a new type. But there are some restrictions on that as well (i.e, structs created this way cannot have “declarations”, e.g. functions).
2 Likes
Here’s an example I just whipped up:
const Foo = struct {
x: i32,
};
const Baz = Embed(Foo, struct {});
fn print_x(entity: anytype) void {
std.log.debug("{d}", .{@field(entity, "x")});
}
test {
std.testing.log_level = .debug;
const foo = Foo{ .x = 10 };
const baz = Baz{ .x = 10 };
print_x(foo);
print_x(baz);
}
fn Embed(comptime E: type, comptime T: type) type {
const t = @typeInfo(T);
comptime var fields = t.@"struct".fields;
const e = @typeInfo(E);
fields = fields ++ e.@"struct".fields;
const new_type = std.builtin.Type{
.@"struct" = .{
.decls = &.{},
.fields = fields,
.layout = t.@"struct".layout,
.is_tuple = t.@"struct".is_tuple,
.backing_integer = null,
},
};
return @Type(new_type);
}
const std = @import("std");
$ zig test embed.zig
[default] (debug): 10
[default] (debug): 10
All 1 tests passed.
In general I don’t think this is a great idea, but I was interested enough to try writing the code.
7 Likes