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). See correct answers below.

union(enum) ?

6 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

2 Likes

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

4 Likes

union(enum)

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

4 Likes