我有一个使用嵌套的When语句的Kotlin代码片段.我注意到,编译器在内部的When语句中需要一个Else块,即使外部的When语句已经涵盖了枚举类的所有情况.代码如下:

enum class Number {
    ONE, TWO, THREE
}

fun main(type: Number) {
    when (type) {
        Number.ONE, Number.TWO -> {
            when (type) {
                Number.ONE -> {}
                Number.TWO -> {}
                // Compiler requires else block here
                else -> {}
            }
        }
        Number.THREE -> {}
    }
}

在这种情况下,100区真的有必要吗?如果是,原因何在?有没有任何文章或文档来解释这种行为?

What did you try and what were you expecting?

我try 使用嵌套的100语句来处理enum类101的不同情况.我原以为内部100语句不需要103块,因为外部100语句已经涵盖了所有可能的枚举值.但是,编译器坚持在内部100语句中包含103块.

推荐答案

when表达式是否详尽取决于它的分支和限定值only.

请参阅spec:

如果when的表达式中至少有一个 以下是事实:

  • 它有一个else的条目;

  • 它有一个限定值,并且至少有以下一项为真:

    • ...
    • 绑定表达式为enum class类型,并使用常量表达式判断其所有枚举值是否相等;
    • ...

when之前和之后的代码并不重要

如果我们只考虑没有else条目的内部when:

when (type) {
    Number.ONE -> {}
    Number.TWO -> {}
}

它显然不是详尽的.typeNumber类型,条目没有涵盖Number的全部3个 case .

根据规范,内部when应该是有效的,因为非穷举的when可以用作语句.

产生的When表达式的类型是其所有条目的类型中的最小上限.如果When表达式不是穷举的,则它的类型为kotlin.Unit,并且只能用作语句.

然而,根据KT-47709,以枚举值must为界值的when个语句是穷尽的.documentation here也同意这一点.然而,我找不到这一点在规范中的位置.它可能不是最新的.

建议的更改

使带有枚举、密封和布尔值的语句成为非穷举语句 主题(以及相应类型的可为空版本)a 编译错误与WHEN表达式一致.这一以贯之 治疗将使开发人员不再需要计算出 源代码中对应的WHEN-WITH-SUBJECT是语句 或表达式,以查看是否由 不管是不是编译器.它将始终处于选中状态.

有关理由的更详细解释,请参见罚单.


也就是说,也有a ticket个人提出了你想要的功能.

目前,如果您确实讨厌空的else块,则可以使用when without作为绑定值,尽管这会产生一些警告(错误地),告诉您将其更改为具有绑定值的when:

when {
    type == Number.ONE -> {}
    type == Number.TWO -> {}
}

Kotlin相关问答推荐

直接从SON解析NonEmptyList

Spring Boot kotlin协程不能并行运行

TzdbZoneRulesProvider 在 java.time 中不工作

如何在 Spring Boot 3 中为内部类提供运行时提示

Kotlin 函数中接收者和参数的类型相同

Kotlin 中的密封和内部有什么区别?

在 Kotlin 中,我可以在集合上有一个条件构建器元素吗?

如何在 IntelliJ 中更改 Kotlin 的this property has a backing field代码编辑器突出显示?

Kotlin 插件错误:无法为类 org.jetbrains.kotlin.gradle.tasks.KotlinCompile 生成代理类

Kotlin:找不到符号类片段或其他 android 类

如何在 Spring WebFlux 的响应正文中流式传输二进制数据

Kotlin:什么是 kotlin.String!类型

从片段(fragment)中的点击事件启动协同程序

Spring Boot:更改属性占位符符号

可以在函数参数中使用解构吗?

@StringRes、@DrawableRes、@LayoutRes等android注释使用kotlin参数进行判断

从另一个列表创建一个列表

Kotlin中默认导入哪些包/函数?

具有多个 parameter的 Kotlin 枚举

使用 Kotlin 按字母对数组进行排序