semi-final switch?

Mathias LANG geod24 at gmail.com
Fri Jun 18 04:40:03 UTC 2021


On Thursday, 17 June 2021 at 21:41:28 UTC, Steven Schveighoffer 
wrote:
> A final switch on an enum complains if you don't handle all the 
> enum's cases. I like this feature.
>
> However, sometimes the data I'm switching on is coming from 
> elsewhere (i.e. a user), and while I want to enforce that the 
> data is valid (it's one of the enum values), I don't want to 
> crash the program if the incoming value is not correct. But 
> final switch doesn't let me declare a default case (to throw an 
> exception instead).
>
> If I use a non-final switch, then my code might forget to 
> handle one of the cases.
>
> Oh, and to throw a monkey wrench in here, the value is a 
> string, not an integer. So I can't use std.conv.to to verify 
> the enum is valid (plus, then I'm running a switch twice).
>
> Any ideas on better ways to handle this?
>
> -Steve

Well, if you receive an `enum` that have an out of bounds value, 
your problem lies in the caller, not the callee. You're breaking 
the most fundamental promise of a type, that is, the values it 
can take. And you obviously also break any `@safe` function by 
feeding it this value.

So instead of thinking in terms of `enum`, I would say, think in 
them of the value, and generate the switch:
```D
SWITCH: switch (myRawValue)
{
     static foreach (EV; NoDuplicates!(EnumMembers!MyEnum))
     {
         case EV:
             // Handle;
             break SWITCH;
     }
     default:
         throw new Exception("Invalid value: " ~ myRawValue);
}
```

Note that this can be encapsulated in its own function, like 
`validateEnum (EnumType) (BaseType!EnumType value)` (not sure if 
we have a `BaseType` template, but you get the point).


More information about the Digitalmars-d-learn mailing list