2017-03-23 30 views
-1

在rx流中使用时,如何在sealed classwhen语句中获得类型安全?当语句的密封类型安全 - kotlin

例如:

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

试图在RX流的上下文中类型安全。

source.map(handleDealOperation) 

回答

0

when表达确实让你键入密封类的安全性,但似乎有一个问题,它在一个变量存储拉姆达的这种特殊情况下。

如果您使用的功能,相反,它会要求你有所有分支,如预期:

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

在我的测试中,用自己的lambda表达式似乎很好地工作,他们正确地要求你做用when的分支详尽无遗,并从它们中返回正确的类型(尝试直接将其作为参数放入map调用中),但将它们存储在变量中时,即使它看起来确实不应该也是如此。

看起来这不是sealed class问题,而是在分配给变量的lambda表达式中的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 

拉姆达通常不会无需最后的编译表达式返回值Int,但它看起来像检查when语句的返回类型时遇到问题。然而,将其分配到一个局部变量,然后再试图返回它给你正确的检查和错误,这并不编译:

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

所以要回到原来的问题,你可以现在使用这个作为破解:

private val handleDealOperation: (DealOperation) -> State.Change = { 
    operation -> 
    val temp = when (operation) { 

    } 
    temp 
} 

如果有人可以正确提交此错误或解释行为,请这样做。

+1

已报告:[KT-17050](https://youtrack.jetbrains.com/issue/KT-17050) – hotkey