密封类型安全的时候陈述 - kotlin

时间:2017-03-23 20:38:33

标签: kotlin

在rx流中使用时,如何在sealed class when语句中获取类型安全性?

例如:

private val handleDealOperation: (DealOperation) -> State.Change = {
            operation ->
            when (operation) {
                //how to enforce type safety? `DealOperation` is a sealed class
            }
        }

尝试在rx流的上下文中进行类型安全。

source.map(handleDealOperation)

1 个答案:

答案 0 :(得分:0)

when表达式确实为密封类提供了类型安全性,但在这种将lambda存储在变量中的特定情况下似乎存在问题。

如果您改用函数,则需要按预期方式拥有所有分支:

private fun handleDealOperation(operation: DealOperation): State.Change =
        when (operation) {
            // this will show a warning on `when`
        }

在我的测试中,使用lambdas本身似乎工作正常,他们正确地要求你使用when的分支进行详尽的处理并从中返回正确的类型(尝试将你的直接放入{{1}调用它作为一个参数),但是将它们存储在变量中会以某种方式编译,即使它看起来真的不应该这样。

看起来这不是map问题,而是分配给变量时lambdas中sealed class表达式的问题。例如,以下代码在运行时编译和崩溃,无论when的参数是什么:

when

例外是:

val doSomething: () -> Int = {
    when ("") { }
}

fun main(args: Array<String>) {
    println(doSomething())
}

如果没有返回Exception in thread "main" java.lang.ClassCastException: kotlin.Unit cannot be cast to java.lang.Number 值的最后一个表达式,lambda通常不会编译,但看起来它无法检查Int语句的返回类型。但是,首先将它分配给局部变量,然后尝试返回它确实会给你正确的检查和错误,这不会编译:

when

所以回到原来的问题,你现在可以用它作为黑客:

val doSomething: () -> Int = {
    val x = when("") {}
    x
}

如果有人可以正确地为此提交错误或解释行为,请执行此操作。