I've recently come across a story of a developer who got told to refactor all of his switch expressions into switch statements because the company just doesn't use switch expressions. I also saw a story where a developer was told that they were no longer allowed to use switch statements because switch expressions were more modern. I have no idea whether these stories are true, but they make an interesting point. Switch statements and switch expressions are similar, but it's not a one-or-the-other choice. They have their own strengths and should be used if the situation calls for it. Let's go for a wander down Switchy Lane!
Spot the Difference
I've gone for a really simple example here. I've created a variable that contains a string description of the type of character I want for my fairytale game, I pass it into the switch and it creates me the appropriate character object.
Switch statements are the ones we all know and leave rotting in a corner because we prefer if-elses love. It's the one on the left and it goes something along the lines of:
Declare your variable (character).
Declare your switch input (characterType).
Create the cases for each potential input, where you assign the variable and then break out back to the main code flow.
Switch expressions look like renegades. It's the one on the right. It goes like:
Declare your switch input (characterType).
Declare your variable and assign the output of the switch to it (character).
Use => to create the case for each input, using _ as the default. You skip the assignment bit because it's being done in the switch declaration, and you can skip the 'case', 'break' and 'default' keywords.
Celebrate about the many lines of code you've saved.
At first glance, if you're not used to switch expressions, it seems like you save a lot of lines of code, but it becomes less readable.
They can also both handle multiple inputs resulting in the same case.
I've had to change the logic here. I'm now passing in a character object and returning an int based on the type of character (I guess maybe pretend that it's returning the amount of that character type present in the game). The aim here is to show that they can both handle cases based on types:
Which Is Better?
It depends.
They're both suitable for different things (and the clue is in their names). One should be used for statements (ie. a declarative piece of code), and one should be used for expressions (ie. code that returns a value). Neither is technically better than the other.
A switch statement is usually better suited to the following situations:
When you have multiple lines of code that need executing for each case, and this includes functions that don't return values.
When you're not assigning a variable as a result of the switch.
When you want fine-grained control over debugging. The debugger steps through each line in a switch statement, but treats a switch expression as one big chonk.
A switch expression is usually better suited to the following situations:
When you've got one line of code that needs executing for each case, and this includes a function that returns a value.
When you need to assign a variable as a result of the switch.
When you need to use relational operators. In the example below, we create a character based on whether a number is below 10, or below/equal to 20.
When you want to use combinations of logical operators. If you ignore the weird logic, this shows how we can check for more complex cases using 'and', 'or' and 'not' in a switch expression.
Summary
At the end of the day, the presence of a switch in your code is a code smell and should be refactored anyway, so all of this is useless knowledge.
I'm partially joking, but you often find that if you've got one switch, it is repeated in multiple places because lots of places rely on the same logic. It can often be a signal that you need to think about polymorphism.
BUT not all switches are code smells. The occasional switch is useful, and now you've got two switch types to play with.
As always, leave your thoughts in the comments below!