Kotlin的智能投射无法简单地实现非空性推论

时间:2019-02-08 13:50:32

标签: java kotlin nullable nullaway

试图了解为什么Kotlin的智能转换在相当简单的用例中不会触发:

val x: Int? = 1

val notNull: Boolean = x != null

if (notNull) {
    val y: Int = x // fails to smart cast
}

但是,如果我们删除中间val,它会起作用:

val x: Int? = 1

if (x != null) {
    val y: Int = x // smart cast works
}

val本质上定义了一个final值,所以我看不出第一个版本不起作用的原因。

在记录中,Java在此用例上的类似用法(https://github.com/uber/NullAway)也失败了,因此可能存在一些潜在的复杂情况,使得不可能进行这种推论吗?

1 个答案:

答案 0 :(得分:0)

您必须那样看。 notNull被分配了truex != null的结果)。在此行之后,没有任何信息可用于编译器在该值与x的可为性之间建立联系。

基本上与立即编写这样的内容相同:

val notNull = true // this is all the compiler knows the time it evaluates the if expression.

if (notNull) {
    val y: Int = x // fails to smart cast
}

您可以为

辩护
if (x != null) {
    val y: Int = x // smart cast works
}

你会说。是的,但是在这种情况下,编译器立即在if块中提供x作为非空值。那是画线的地方。如果您不停在某个地方,则会导致大量推断,从而降低了编译过程的效率。