用密封类强制编译错误

对于密封类,当expression式返回结果时,可以使用穷举expression式并省略else子句:

 sealed class SealedClass { class First : SealedClass() class Second : SealedClass() } fun test(sealedClass: SealedClass) : String = when (sealedClass) { is SealedClass.First -> "First" is SealedClass.Second -> "Second" } 

现在,如果我要添加ThirdSealedClass ,编译器会抱怨test()中的whenexpression式不完全,我需要为Thirdelse添加一个子句。

我想知道,但是如果这个检查也可以强制执行test()不返回任何东西时:

 fun test(sealedClass: SealedClass) { when (sealedClass) { is SealedClass.First -> doSomething() is SealedClass.Second -> doSomethingElse() } } 

如果添加Third这个片段不会中断。 我可以在时间之前添加一个return语句,但如果其中一个子句的返回types不是Unit ,则可能很容易被遗忘,并可能中断。

我怎样才能确保我不会忘记在我的when子句中添加一个分支?

强制执行的方法是通过使用它的值来使其成为一个expression式:

 sealed class SealedClass { class First : SealedClass() class Second : SealedClass() class Third : SealedClass() } fun test(sealedClass: SealedClass) { val x = when (sealedClass) { is SealedClass.First -> doSomething() is SealedClass.Second -> doSomethingElse() } // ERROR here // or when (sealedClass) { is SealedClass.First -> doSomething() is SealedClass.Second -> doSomethingElse() }.let {} // ERROR here } 

在Voddan的答案的启发下,你可以建立一个叫做safe的属性,你可以使用:

 val Any?.safe get() = Unit 

使用:

 when (sealedClass) { is SealedClass.First -> doSomething() is SealedClass.Second -> doSomethingElse() }.safe 

我认为它提供了一个更清晰的信息,而不仅仅是追加.let{}或将结果赋值给一个值。


Kotlin追踪器有一个公开的问题 ,认为它支持“密封的事件”。