# Using both \`\_\` and \`else\` in switch prongs

**URL:** <https://ziggit.dev/t/using-both-and-else-in-switch-prongs/5986>\
**Category:** Brainstorming\
**Tags:** language\
**Created:** [September 14, 2024, 2:32am UTC](https://ziggit.dev/t/using-both-and-else-in-switch-prongs/5986 "2024-09-14T02:32:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [September 14, 2024, 2:32am UTC](https://ziggit.dev/t/using-both-and-else-in-switch-prongs/5986/1 "2024-09-14T02:32:33Z")

</div>

I have a use-case which might call for using both the `_` and the `else` prongs in a switch. This currently is a compiler error. Do you think this should be allowed?

In my use case, I am deserailizing a byte stream. I don’t trust the byte stream so my Enum must be able to handle all possible values. I also want to make sure I get the right value of the enum.

```zig
/// Mailbox Types
///
/// Ref: IEC 61158-4-12:2019 5.6
pub const MailboxType = enum(u4) {
    /// error
    ERR = 0x00,
    /// ADS over EtherCAT (AoE)
    AoE,
    /// Ethernet over EtherCAT (EoE)
    EoE,
    /// CAN Application Protocol over EtherCAT (CoE)
    CoE,
    /// File Access over EtherCAT (FoE)
    FoE,
    /// Servo Drive Profile over EtherCAT (SoE)
    SoE,
    /// Vendor Specfic over EtherCAT (VoE)
    VoE = 0x0f,
    _,
};

pub const InContent = union(enum) {
    coe: coe.InContent,

    // TODO: implement other protocols

    /// identifiy the content of the mailbox in buffer
    fn identify(buf: []const u8) !std.meta.Tag(InContent) {
        var fbs = std.io.fixedBufferStream(buf);
        const reader = fbs.reader();
        const mbx_header = try wire.packFromECatReader(Header, reader);

        return switch (mbx_header.type) {
            .CoE => return .coe,
            _ => return error.InvalidMbxProtocol,
            else => return error.NotImplemented,
        };
    }
};

```

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [September 14, 2024, 2:37am UTC](https://ziggit.dev/t/using-both-and-else-in-switch-prongs/5986/2 "2024-09-14T02:37:35Z")

</div>

ah, there is already a proposal

> <https://github.com/ziglang/zig/issues/12250>
>
> Currently when using switch statements with non-exhaustive enums you are able to… use it in the following 2 ways as explained in the documentation:
> \> A switch on a non-exhaustive enum can include a '\_' prong as an alternative to an \*\*else\*\* prong with the difference being that it makes it a compile error if all the known tag names are not handled by the switch. 
> \`\`\`zig
> const Enum = enum(u32)
> {
> A = 1,
> B = 2,
> C = 44,
> \_
> };
> 
> fn some\_function(value: Enum) void
> {
> // Compiles as all tags are handled
> switch(value)
> {
> .A =\> {},
> .B =\> {},
> .C =\> {},
> \_ =\> {}, // Unnamed tags go here
> }
> 
> // Compiles as all tags are handled
> switch(value)
> {
> .A =\> {},
> .B =\> {},
> else =\> {}, // Both named and unnamed tags go here
> }
> }
> \`\`\`
> As I had not read that part of the documentation and I have only been using '\_' prongs, I was expecting the following code to work as well:
> \`\`\`zig
> fn some\_other\_function(value: Enum) void
> {
> // Does not compile giving "error: else and '\_' prong in switch expression"
> switch(value)
> {
> .A =\> {},
> .C =\> {},
> else =\> {}, // Named tags go here so .B in this case
> \_ =\> {}, // Unnamed tags go here
> }
> }
> \`\`\`
> The idea I had in my head was that the '\_' prong would catch the unnamed tags and the else prong the named tags. I was running into this when I was using the Win32 API and had written my own enum for the WM\_NOTIFY values. As the part of the code I was working on did not need all of the named tags I thought I could add the else prong to filter those out.
> 
> I asked about this on IRC and more people thought it worked the way I thought it would work. So I opened this issue to see if it is viable to add something like this to the language. I have no real preference for any kind of syntax for this but the way I had written it down seemed really natural.
> One thing that did struck me when I was making this issue was that in my head I saw else as something for named tags and '\_' for unnamed tags so it didn't even come up to me that using else in non-exhausted enums would actually also catch the unnamed tags.
