Code_Life
Code_Life

Reputation: 5902

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)
        )
    }

Upvotes: 9

Views: 11428

Answers (2)

Willi Mentzel
Willi Mentzel

Reputation: 29884

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"

Upvotes: 4

Sergio
Sergio

Reputation: 30715

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.

Upvotes: 13

Related Questions