[swift-evolution] Testing enum cases with associated values
Andy Chou
acchou2 at gmail.com
Tue Jan 17 18:15:09 CST 2017
Enums with associated values can be very useful in Swift, but once you add associated values you lose some properties, especially equality:
```
enum AuthenticationResponse {
case success
case alert(Alert)
case reauthenticate
}
```
Testing for a specific case requires a switch statement or the if pattern match syntax:
if case .success = response { … }
But while this works well for control flow, it doesn’t work well for cases where we want a Bool, such as assert(). There are also common situations with lists and libraries like RxSwift where a filtering function uses a Bool valued closure. In these situations the best we can do is write functions like:
```
enum AuthenticationResponse {
case success
case alert(Alert)
case reauthenticate
var isSuccess: Bool {
if case .success = self {
return true
} else {
return false
}
}
var isReauthenticate: Bool {
if case .reauthenticate = self {
return true
} else {
return false
}
}
var isAlert: Bool {
if case .alert(_) = self {
return true
} else {
return false
}
}
}
```
Any suggestions better than writing out each of these functions explicitly?
The conditional conformances proposal coming in Swift 4 solves some of this issue, but not completely. If Alert isn’t Equatable, it is still useful to test whether the result is .success. For example:
assert(response == .success)
This is perfectly intelligible and I would argue that equality should be defined for enums with associated values omitted:
assert(response == .alert)
Here we are ignoring the associated values, and merely checking if the enum case is the same.
Andy
More information about the swift-evolution
mailing list