试图了解为什么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)也失败了,因此可能存在一些潜在的复杂情况,使得不可能进行这种推论吗?
答案 0 :(得分:0)
您必须那样看。 notNull
被分配了true
(x != 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作为非空值。那是画线的地方。如果您不停在某个地方,则会导致大量推断,从而降低了编译过程的效率。