Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid else condition in 'When' in kotlin

As per documentation of When in Kotlin, else is not mandatory if the compiler knows all the values are covered. This is very in case of emums or sealed class but how to do it in case of arrays for numbers 1 to 5 (startRating).

private fun starMapping(startRating: Int): String {

    return when (startRating) {
        1 -> "Perfect"
        2 -> "Great"
        3-> "Okay"
        4-> "Bad"
        5-> "Terrible"
        // don't want to add else as I believe it is prone to errors.
    }
}

Something similar to this

return when (AutoCompleteRowType.values()[viewType]) {
        AutoCompleteRowType.ITEM -> ItemView(
                LayoutInflater.from(parent.context).inflate(R.layout.item_venue_autocomplete_item_info, parent, false))

        AutoCompleteRowType.SECTION -> SectionView(
                LayoutInflater.from(parent.context).inflate(R.layout.item_venue_autocomplete_section, parent, false)
        )
    }
like image 401
Code_Life Avatar asked Aug 04 '20 08:08

Code_Life


People also ask

Is else mandatory in when Kotlin?

If when is used as an expression, the else branch is mandatory, unless the compiler can prove that all possible cases are covered with branch conditions, for example, with enum class entries and sealed class subtypes).

How do I get rid of if-else in Kotlin?

Kotlin if-else Expression We can remove the curly braces of if-else body by writing if expression in only one statement. For example: fun main(args: Array<String>) { val num1 = 10.

How do I choose between switches and when in Kotlin?

Kotlin does not provide any option to write a switch-case statement. However, Kotlin provides an option to implement when() which works exactly the same way switch works in other programming languages.


2 Answers

Using when statement it is impossible to exclude else clause in case of using ints, because compiler doesn't know what to return if startRating is not in 1..5 range. You can, for example, throw an IllegalStateException if the value is not in the required range:

private fun starMapping(startRating: Int): String {
    return when (startRating) {
        1 -> "Perfect"
        2 -> "Great"
        3-> "Okay"
        4-> "Bad"
        5 -> "Terrible"
        else -> throw IllegalStateException("Invalid rating param value")
    }
}

Or you can do something like this:

return when {
    startRating <= 1 -> "Perfect"
    startRating == 2 -> "Great"
    startRating == 3 -> "Okay"
    startRating == 4 -> "Bad"
    else -> "Terrible"
}

But else clause is required.

like image 89
Sergey Avatar answered Sep 21 '22 12:09

Sergey


You may not want to use when for this at all. Here is what I would suggest:

You could create an enum class like so:

enum class Rating(val score: Int) {
  Perfect(1),
  Great(2),
  Okay(3),
  Bad(4),
  Terrible(5)
}

And utilise it like that:

fun ratingForScore(score: Int) = Rating.values().firstOrNull {
    it.score == score
}?.toString()

ratingForScore(1) // "Perfect"
like image 39
Willi Mentzel Avatar answered Sep 19 '22 12:09

Willi Mentzel