[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