当表达式上的 Kotlin 智能转换

san*_*den 2 kotlin

我对 kotlin 智能转换感到困惑。在我看来if(condition) / else相当于when(condition) true -> /false ->,但是智能转换不适用于我的 when 表达式。

我正在使用科特林 1.5.30

data class Person(val name: String)
data class Address(val id: String, val person: Person?)

fun getPersonFromAddress(address: Address?): String {
    return if (address?.person != null) {
        address.person.name
    } else {
        "Not found"
    }
}

fun getPersonFromAddress(address: Address?): String {
    return when (address?.person != null) {
        true -> address.person.name // <-- Does not compile
        false -> "Not found"
    }
}
Run Code Online (Sandbox Code Playgroud)

Ten*_*r04 5

由于其分析方式的原因,if 表达式会转换为when 表达式,如下所示:

fun getPersonFromAddress(address: Address?): String {
    return when {
        address?.person != null -> address.person.name
        else -> "Not found"
    }
}
Run Code Online (Sandbox Code Playgroud)

它将编译。

有参数的A与没有参数when的不同。when首先计算参数中的表达式,仅计算一次。然后将该结果(而不是表达式)与每种情况进行比较。因此,就其评估方式而言,它与 if/else 不同。

正如 @broot 在评论中提到的,您还可以将空检查推迟到像这样的 when 情况,并且智能转换将起作用,因为它在该分支上检查它:

fun getPersonFromAddress(address: Address?): String {
    return when(address?.person) {
        null -> "Not found"
        else -> address.person.name
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您要将带有条件的 while 语句的尝试转换为 if/else 语法,则它将如下所示:

fun getPersonFromAddress2(address: Address?): String {
    val condition = address?.person != null
    return if (condition) {
        address.person.name
    } else {
        "Not found"
    }
}
Run Code Online (Sandbox Code Playgroud)

这也不会编译

我想原因是编译器在这些条件下必须分析的智能转换的复杂性可能会通过添加额外的间接检查而呈指数级增长。