Kotlin's `when` with enums: `else` considered harmful
Tags: kotlin
Published: 2024-06-01 07:05:48

---
title: Kotlin's `when` with enums: `else` considered harmful
published: true
date: 2024-06-01 07:03:26 UTC
tags: Kotlin
canonical_url: https://www.paleblueapps.com/rockandnull/kotlin-when-enums-avoiding-else/
---

 ![Kotlin's `when` with enums: `else` considered harmful](https://images.unsplash.com/photo-1563393934034-21b781d905ef?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fHNhZmV0eXxlbnwwfHx8fDE3MTcyMjUxMjF8MA&ixlib=rb-4.0.3&q=80&w=2000)

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!