DEV Community

Dayvster 🌊
Dayvster 🌊

Posted on β€’ Originally published at dayvster.com

1

Building Blocks Of Zig: Unions

What are Zig Unions?

Zig unions are a way to represent a type that can be one of several different types. However only one of the types can be active at any given time. Think of it as a way to represent multiple possible types of a value in a single variable.

That may sound a bit confusing at first but it is actually quite simple. Let's take a look at an example to understand how Zig unions work.

How To Create A Union In Zig

Creating a union in Zig is similar to how you would define a struct.


const ValidInput = union {
  int: i32,
  string: []const u8,
  float: f32,
};

// And to use the union we simply:
const input = ValidInput{ .int = 42 };
Enter fullscreen mode Exit fullscreen mode

This is what we call a Bare Union. It is a union that does not have a tag, this means that the memory layout of the union is not necessarily the same across the board. This is essentially because a bare union does not have a tag to tell us which field is active. So accessing a field in the union that is not active will result in a problem.

What is a Tagged Union in Zig?

A tagged union is a union that has a tag. For this we use an enum to define the tag. This way we can tell which field is currently active in the union.

const Tag = enum {
  Int,
  String,
  Float,
};
const TaggedValidInput = union(Tag) {
  Int: i32,
  String: []const u8,
  Float: f32,
};
Enter fullscreen mode Exit fullscreen mode

As you see in the example above we define an enum called Tag that has three possible values Int, String and Float. We then define a union called TaggedValidInput that uses the Tag enum as a tag. This way we can tell which field is active in the union.

That's pretty nifty right? Now here's the cool part, we can use the switch statement to check which field is active in the union and act accordingly.

const input = TaggedValidInput{ .Int = 42 };

switch (input) {
  .Int => {
    std.log.info("Int: {d}\n", .{input.Int});
  },
  .String => {
    std.log.info("String: {s}\n", .{input.String});
  },
  .Float => {
    std.log.info("Float: {f}\n", .{input.Float});
  },
}

Enter fullscreen mode Exit fullscreen mode

Conclusion

So there it is, we've learned about Zig unions and how they can be used to define types that can have multiple possible value types, I know it may seem a bit confusing at first but once you get the hang of it you'll see how powerful unions can be. I'd recommend using them whenever you are dealing with values that can have multiple different possible types, such as: configuration values, user input, API's with different return types for the same field etc. etc.

I hope you enjoyed this post and learned something new about Zig. If you have any questions or comments feel free to reach out to me on Twitter

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

Sentry image

See why 4M developers consider Sentry, β€œnot bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

πŸ‘‹ Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay