Kotlin when()局部变量介绍

Yon*_*ree 5 pattern-matching kotlin

假设我有一个昂贵的函数doHardThings(),可以返回各种不同的类型,我想根据返回的类型采取行动.在Scala中,这是match构造的常见用法:

def hardThings() = doHardThings() match {
     case a: OneResult => // Do stuff with a
     case b: OtherResult => // Do stuff with b
}
Run Code Online (Sandbox Code Playgroud)

我正在努力弄清楚如何在Kotlin中干净利落地做到这一点而不引入一个临时变量doHardThings():

fun hardThings() = when(doHardThings()) {
     is OneResult -> // Do stuff... with what?
     is OtherResult -> // Etc...
}
Run Code Online (Sandbox Code Playgroud)

对于这个常见用例,什么是惯用的Kotlin模式?

zsm*_*b13 6

更新:现在可以从Kotlin 1.3获得.语法如下:

fun hardThings() = when (val result = doHardThings()) {
     is OneResult -> // use result
     is OtherResult -> // use result some other way
}
Run Code Online (Sandbox Code Playgroud)

老答案:

我认为你只需要为该函数设置一个块体,并将操作结果保存到局部变量中.不可否认,这不像Scala版本那么整洁.

when带有is检查的目的是传入一个变量,然后在你的分支中使用同一个变量,因为如果它通过检查,它会被智能强制转换为它所检查的类型,你可以轻松地访问它的方法和属性.

fun hardThings() {
    val result = doHardThings()
    when(result) {
        is OneResult ->   // result smart cast to OneResult
        is OtherResult -> // result smart cast to OtherResult
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在某种程度上围绕您的操作编写某种包装器,以便它只评估它一次,否则返回缓存的结果,但它可能不值得它引入的复杂性.

由@mfulton26创建变量的另一个解决方案是使用let():

fun hardThings() = doHardThings().let {
    when(it) {
        is OneResult ->   // it smart cast to OneResult
        is OtherResult -> // it smart cast to OtherResult
    }
}
Run Code Online (Sandbox Code Playgroud)