Kotlin’s `when` with enums: `else` considered harmful

Kotlin’s `when` with enums: `else` considered harmful

Kotlin’s when statement is a versatile and powerful tool for handling conditional logic. When working with enums, it can feel natural to use an else clause as a catch-all for cases you haven’t explicitly defined. However, this seemingly convenient practice can introduce subtle risks into your codebase. Let’s explore why it’s often better to favor exhaustive when statements without else when dealing with enums.

The case for exhaustive when statements

When you omit the else clause and your when statement doesn’t cover all possible enum values, Kotlin’s compiler will raise an error. A new enum value – without an explicit handling case, it would silently fall into the else block, potentially leading to unexpected behavior that’s difficult to trace. This compiler error acts as a safety net, immediately alerting you to potential oversights and forcing you to explicitly define the behavior of the new enum value.

Let’s consider an enum representing different payment methods:

enum class PaymentMethod {
CREDIT_CARD,
DEBIT_CARD,
PAYPAL,
APPLE_PAY
}

fun processPayment(method: PaymentMethod) {
when (method) {
PaymentMethod.CREDIT_CARD -> handleCreditCard()
PaymentMethod.DEBIT_CARD -> handleDebitCard()
else -> handleOtherPayment() // Catch-all, potential risk
}
}

With “Else” (Less Safe)

fun processPayment(method: PaymentMethod) {
when (method) {
PaymentMethod.CREDIT_CARD -> handleCreditCard()
PaymentMethod.DEBIT_CARD -> handleDebitCard()
PaymentMethod.PAYPAL -> handleOtherPayment()
PaymentMethod.APPLE_PAY -> handleOtherPayment()
}
}

Without “Else” (More Safe)

In the last example, the compiler will flag an error if a new payment method is added to the enum without a corresponding case in the when statement.

Exceptions to the rule

While exhaustive when statements are generally preferred, there are cases where an else clause makes sense.

If there truly is a default action applicable to all enum values not explicitly handled, an else is appropriate. Another case is when you’re working with an enum from an external library where you cannot guarantee all values are covered, an else might be necessary.

Conclusion

In general, favor exhaustive when statements without else when working with enums for enhanced type safety and error prevention. By doing this you can embrace the compiler’s help in guiding you toward a less error-prone code over the lifetime of your project. Consider the else clause only when it represents a true default behavior or in exceptional circumstances.

Happy coding!