Tagged union

Is there a way to “save keystrokes” in a tagged union like this? I’d like to forego the doubling of “foo” and “bar”

   pub const Content = union(Content.Types) {
      foo: []const u8,
      bar: Bar,
      pub const Types = enum { foo, bar, };
   };

I stuck “Types” inside “Content”, but, certainly, it could have been external. one might ask: why make the enum at all? Well, I want to use the type in switch expressions. So, perhaps this is another way of asking: “why can’t we do a switch statement on union members without making it a tagged union tied to an enum (redundantly) naming those fields?”

No. But the good new is that you’ll get a compile error if the enum and the tagged union are out of sync (don’t contain the same fields).

union(enum) ?

3 Likes

I assumed they wanted to use the enum separately, but you may be right!

The enum type of a tagged union can always be accessed via

const Type = @typeInfo(Content).@"union".tag_type.?;

You can even assign explicit values to the enum members of a tagged union if you provide a backing integer:

const Content = union(enum(u32)) {
    foo: []const u8 = 123,
    bar: Bar = 456,
};

Because a plain union doesn’t store any info about which field’s currently active (at least not with runtime safety disabled), so there would be nothing to switch on

Or, if you prefer, std.meta.Tag. Same thing.

1 Like

union(enum)

Crap! It was right there all along! Thanks for pointing out the obvious to which I was oblivious.