【问题标题】:Why in kotlin "something != null || return" does not perform smartcast, but "if (something == null) return" yes为什么在 kotlin 中 \"something != null || return\" 不执行智能转换,但 \"if (something == null) return\" 是
【发布时间】:2022-11-02 02:02:30
【问题描述】:
给定一个函数。例如:
suspend fun getUser(userId: Int): User? {
val result: UserApiResult? = fetchTheApi(userId)
//result != null || return null // Not smartcast
if (result == null) return null // Will make an smartcast of result from UserApiResult? to UserApiResult
return User(result.email, result.name)
}
在我的 IDE 中,特别是 Android Studio。第一个条件不会执行 smartcast,即使它明显地做与第二个条件相同的事情(除非它在引擎盖下做一些黑暗的事情)。
【问题讨论】:
标签:
kotlin
null
conditional-statements
【解决方案1】:
没有好的技术的智能施法不生效的原因。
但它比你认为的要复杂。 result != null || return null 编译的唯一原因是因为return null 具有Nothing 类型,并且您可以将Nothing 强制转换为任何内容(在这种情况下:Boolean)。
编译器应该能够推断出result != null,否则我们将获得Nothing 的实例(这是不可能的)。但我个人很高兴我永远不必在代码审查中看到|| return null,我想这不起作用的原因不是 Koltin 开发人员的错误。
我的猜测是编译器将Nothing 从return null 强制转换为Boolean,并失去了该分支无法返回的语义。
【解决方案2】:
我认为这只是当前编译器的一个限制。使用当前编译器构建该代码会失败,但如果您切换到新的 K2 编译器(目前仍处于 Alpha 阶段)编译成功。
例子:
fun returnSomething(): String? = null
fun doSomething(): String? {
val result: String? = returnSomething()
result != null || return null
return result.length.toString()
}
fun main() {
println(doSomething())
}
构建输出:
Kotlin: kotlinc-jvm 1.7.10 (JRE 1.8.0_212-b10)
Kotlin: ATTENTION!
This build uses experimental K2 compiler:
-Xuse-k2
Kotlin: performing incremental compilation analysis
Updating dependency information… [coroutines-test]
Running 'after' tasks
Finished, saving caches…
Executing post-compile tasks...
Synchronizing output directories...
01/11/2022, 18:01 - Build completed successfully with 4 warnings in 9 sec, 296 ms