Swift When - supporting switch expressions in Swift!
What is it?
Basically, it allows you to (kinda) use switch statement as an expression - compare a value against a bunch of cases and return a single value based on the which case passes.
This functionality exists in most popular languages as it leads to more elegant and concise code (e.g, C#, Java, Kotlin). Consider this example:
public enum Colors: WhenCompliant {
case red, blue, green
var hexString: String {
when(self) { // isn't this nice?
Colors.red => "#FF0000"
Colors.green => "#00F000"
Colors.blue => "#0000FF"
}
}
}
OK, but why?
Because I wrote something like this way too many times:
public enum Colors: WhenCompliant {
case red, blue, green
var hexString: String {
switch self { // :(
case Colors.red:
return "#FF0000"
case Colors.green:
return "#00F000"
case Colors.blue:
return "#0000FF"
}
}
}
Writing out a full switch to transform a single enum value into something else, alongside all the cases, colons and explicit returns is unnecessarily verbose and ceremonial.
The same is true for a bunch of if-else if-...-else
that all return the same value:
func describeNumber(_ n: Int) -> String {
if n > 0 {
return "positive"
} else if n < 0 {
return "negative"
} else {
return "zero"
}
}
This package aims to solve those issues.
What it can do
Use with enums
To use an enum with when
, it needs to be WhenCompliant
, which implies being Hashable
and CaseIterable
:
enum Colors: WhenCompliant {
case red, blue, green
}
After that, things get really simple:
func describeColor(_ color: Colors) {
let description = when(color) {
Colors.red => "red"
Colors.blue => "blue"
Colors.green => "green"
}
print(description)
}
When called, when
checks if all enum cases are taken care of. If not, a runtime error is thrown.
Alternatively, you can specify the default clause:
func describeColor(_ color: Colors) {
let description = when(color) {
Colors.red => "red"
Colors.blue => "blue"
"other" // the default clause
}
print(description)
}
If multiple cases should map to the same result, wrap them in an array:
func describeColor(_ color: Colors) {
let description = when(color) {
[Colors.red, Colors.blue] => "redOrBlue"
Colors.green => "green"
}
print(description)
}
Use with boolean expressions
Alternatively, when can be used as a generic shorthand for a bunch of if-else if-...-else statements that all return the same value. Check out this example:
func describeNumber(_ n: Int) -> String {
when {
(n > 0) => "positive"
(n < 0) => "negative"
"zero" // default clause
}!
}
What it can't do
when
can't work with enums that have associated values. Consequently, it also can't unwrap associated values (i.e, nocase let
).switch
offers compile-time guarantee that all cases are covered.when
does that at runtime.
Installation
This component is distrubuted as a Swift package. Just add this URL to your package list:
https://github.com/globulus/swift-when
Changelog
- 1.0.0 - Initial release.