Kotlin when in action

The when expression in Kotlin is a powerful conditional statement that can be used in place of the switch statement found in many other languages. It is versatile and can handle multiple types of conditions. Let’s take a look at when an expression is used as a statement.

Basic Syntax

The basic syntax of a when expression is very similar to a switch statement in Java. However, unlike in Java where you need to use the break keyword for each case, you do not need to use break for each case in a when expression.

when (variable) {
    case1 -> result1
    case2 -> result2
    else -> resultN
}

Usage scenarios:

As a Statement

This is very simple use case how you can use when as statement, if you enter all possible cases for example from enum you do not need to add else branch

enum class Result {
    SUCCESS,FAILURE,IN_PROGRESS
} 

fun processResult(result: Result) {
        when (result) {
            Result.SUCCESS -> println("Success")
            Result.FAILURE -> println("Failure")
            Result.IN_PROGRESS -> println("In progress")
        }
    }

Combining Options

In this example, you can see how different options can be combined to produce the same result. However, do not forget to add an else branch or ensure that all options are covered. If you miss this step, nothing may happen, and you won’t know what went wrong.

 fun combineOptions(value: Int){
        when(value){
            1,3,5,7,9 -> println("Odd")
            2,4,6,8,10 -> println("Even")
            else -> println("Unknown")
        }
    }

Scoped variable

You might encounter a use case where you need to call a function or remote service and decide which flow to continue based on the response.

    fun scopedVariableInWhen(){
        when(val response = callHttpService()){
            Result.SUCCESS -> println("Success")
            Result.FAILURE -> println("Failure")
            Result.IN_PROGRESS -> println("In progress")
        }
    }
    
    fun callHttpService(): Result {
        return Result.SUCCESS
    }
    
    enum class Result {
        SUCCESS,FAILURE,IN_PROGRESS
    }

Without argument

This example focuses on how you can use when without arguments while adding the conditions you need to decide the flow. It is a very nice feature, and I have used it in many use cases because it is much more concise and readable than using if-else statements. However, you must ensure that all options are covered or include an else branch. Otherwise, if no conditions match, nothing will happen, leading to potential issues.

    fun whenWithoutArguments(order: Order){
        when{
            order.amount > 1000 && order.currency == Currency.EUR -> println("High value order in EUR")
            order.amount < 1000 && order.currency == Currency.USD -> println("Low value order in USD")
            order.amount > 1000 && order.currency == Currency.GBP -> println("High value order in GBP")
            else -> println("Not covered case")
        }
    }

    data class Order(val id: Int, val amount: Double, val currency: Currency)

    enum class Currency {
        EUR,USD,GBP
    }

Smart casting

There is a very interesting approach to using interfaces and smart casts. However, in the next lecture, we will focus on sealed interfaces which is more usefull with when expression.

interface Message

data class TextMessage(val text: String) : Message
data class ImageMessage(val imageUrl: String) : Message
data class VideoMessage(val videoUrl: String, val length: Int) : Message

// Function to handle the message
fun handleMessage(message: Message): String {
    return when (message) {
        is TextMessage -> "Handling text message: ${message.text}"
        is ImageMessage -> "Handling image message with URL: ${message.imageUrl}"
        is VideoMessage -> "Handling video message with URL: ${message.videoUrl} and length: ${message.length} seconds"
        else -> "Unknown message type"
    }
}

Conclusion

In conclusion, the when expression in Kotlin offers a versatile and concise alternative to the traditional switch statement found in other languages. It simplifies handling multiple conditions without requiring the break keyword and supports various use cases such as combining options, scoped variables, and smart casting. However, it’s crucial to cover all possible conditions or include an else branch to prevent unexpected behavior. The next article will explore how when can be effectively combined with sealed interfaces for even more powerful conditional logic.

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *

×