2

试图理解为什么 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)对于此类用例也失败了,因此可能存在一些潜在的复杂性使得此类推论变得不可能?

4

1 回答 1

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 提供为非空值。这就是它划清界限的地方。如果您不停止某处,您最终会进行大量推理,从而降低编译过程的效率。

于 2019-02-09T16:39:36.900 回答