在 kotlin 中避免 'When' 中的其他条件

Avoid else condition in 'When' in kotlin

根据 Kotlin 中 When 的文档,如果编译器知道所有值都被覆盖,则 else 不是强制性的。这在 emums 或密封 class 的情况下非常有用,但是在数字 1 到 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.
    }
}

类似的内容

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

使用 when 语句在使用整数的情况下不可能排除 else 子句,因为编译器不知道 return 如果 startRating 不是在 1..5 范围内。例如,如果值不在要求的范围内,您可以抛出 IllegalStateException

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

或者你可以这样做:

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

但是 else 子句是必需的。

您可能根本不想为此使用 when。这是我的建议:

您可以像这样创建枚举 class:

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

并像这样利用它:

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

ratingForScore(1) // "Perfect"