【问题标题】:kotlin when expression autocastkotlin 表达式自动转换时
【发布时间】:2019-02-14 15:42:08
【问题描述】:

我希望以下 kotlin 代码能够正常工作:

val result: Try<Option<String>> = Success(Some("test"))

val test = when {
    result is Success && result.value is Some -> result.value.t // not working
    result is Success && result.value is None -> "Empty result"
    result is Failure -> "Call failed!"
    else -> "no match!"
}

我将箭头库用于 Try 和 Option monad。

不幸的是,我只能访问第一个条件“is Success”的值,而不能访问第二个条件“is Some”的值。所以,我只能做“result.value”,然后我得到一个String的Option。

我错过了什么吗?这将为我节省很多内部“.map”和“.fold”调用。

更新:

我需要先施放它,这很难看:

result is Success && result.value is Some -> (result.value as Some<String>).t

【问题讨论】:

    标签: kotlin arrow-kt


    【解决方案1】:

    我在 IntelliJ 中使用 Kotlin 1.3.21 尝试了您的示例。 它显示了问题的原因:

    您需要将result.value 提取为变量才能使其工作。我找到了下面的sn-p来解决它

    
    val result: Try<Option<String>> = Success(Some("test"))
    
    val test = when (result) {
        is Success -> when(val value = result.value) {
            is Some -> value.t
            is None -> "None"
        }
        is Failure -> "Call failed!"
        else -> "no match!"
    }
    

    我使用带有声明语法的 Kotlin 1.3.x when。

    您也可以使用 Arrow API 来获得类似的结果:

    val test = result.fold(
        ifSuccess = { it.getOrElse { "None" }},
        ifFailure = { "Call failed!" }
    )
    

    这里您不需要在when 中包含else 子句。

    【讨论】:

      【解决方案2】:

      您可以像这样简化模式匹配:

      val test = result
        .map { it.getOrElse { "Empty result"} }
        .getOrElse { "Call failed!" }
      

      这有点详尽,不需要else 替代

      或者,如果您不关心引发的异常,您可以在Try 上使用toOption:

      val test = result
        .toOption()
        .getOrElse { "No value!!" }
      

      但是,这有一些明显的信息丢失。

      我个人会将Try 实例冒泡给结果的使用者,将内部Option 与.map 折叠起来,以便最终结果的类型为Try&lt;String&gt;,并让使用者处理错误。

      但是,这在很大程度上取决于问题的实际背景。

      【讨论】:

      • 如果该值实际上是字符串"Empty result"、"Call failed!" 或"No value!!",该怎么办?
      • 是的,这很糟糕。但是,这是一个关于设计初衷的问题。问题是关于转换和控制流......在理想的世界中,最终结果将是一个封闭的层次结构(即密封类)来表示所有 3 种状态并在 UI 上呈现它
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多