为什么 Kotlin 的 null 安全性不能与局部变量初始值设定项一起正常工作?
Why does Kotlin's null safety not work properly with local variable initializers?
请看这段代码:
fun localVarNullSafety1(){
var number: Double? = 3.0
val sum = 2.0 + number // does not compile (Type mismatch: inferred type is Double? but Double was expected)
}
fun localVarNullSafety1(){
var number: Double? = null
number = 3.0
val sum = 2.0 + number // compiles fine
}
我认为上面的代码由语义相同的函数组成——局部变量不会超出范围,它们对执行线程而言是局部的。在我看来,第一个函数没有理由不编译。
我认为 Kotlin 的智能转换应该考虑变量初始化。
我是否漏掉了一些明显的东西?
这在 KT-13663 中进行了讨论,在撰写本文时它仍然是一个开放的票证。
他们正在考虑更一般的情况(请注意 T?
是 T
的超类型):
val x: Supertype = Subtype()
var y: Supertype = Subtype()
并决定在 val
的情况下,x
在此处具有类型 Subtype
没有意义,否则您可以不在其中编写类型注释第一名。
虽然这对 var
s 可能有意义,但如果仅对 var
s 实施智能转换,则 vars
和 val
s 将具有不一致的行为关于他们的类型:
val x: Supertype = Subtype()
var y: Supertype = Subtype()
// inconsistent:
x.someSubtypeStuff() // doesn't work, x is a Supertype
y.someSubtypeStuff() // works, y is smart casted to Subtype
所以他们最终没有为初始化实现智能转换。
由于工单还未开放,此功能很可能会在未来的 Kotlin 版本中实现。它可能只支持 var
s,同时支持 var
s 和 val
s,或者只支持可为 null 的类型。让我们期待最好的结果吧!
请看这段代码:
fun localVarNullSafety1(){
var number: Double? = 3.0
val sum = 2.0 + number // does not compile (Type mismatch: inferred type is Double? but Double was expected)
}
fun localVarNullSafety1(){
var number: Double? = null
number = 3.0
val sum = 2.0 + number // compiles fine
}
我认为上面的代码由语义相同的函数组成——局部变量不会超出范围,它们对执行线程而言是局部的。在我看来,第一个函数没有理由不编译。
我认为 Kotlin 的智能转换应该考虑变量初始化。
我是否漏掉了一些明显的东西?
这在 KT-13663 中进行了讨论,在撰写本文时它仍然是一个开放的票证。
他们正在考虑更一般的情况(请注意 T?
是 T
的超类型):
val x: Supertype = Subtype()
var y: Supertype = Subtype()
并决定在 val
的情况下,x
在此处具有类型 Subtype
没有意义,否则您可以不在其中编写类型注释第一名。
虽然这对 var
s 可能有意义,但如果仅对 var
s 实施智能转换,则 vars
和 val
s 将具有不一致的行为关于他们的类型:
val x: Supertype = Subtype()
var y: Supertype = Subtype()
// inconsistent:
x.someSubtypeStuff() // doesn't work, x is a Supertype
y.someSubtypeStuff() // works, y is smart casted to Subtype
所以他们最终没有为初始化实现智能转换。
由于工单还未开放,此功能很可能会在未来的 Kotlin 版本中实现。它可能只支持 var
s,同时支持 var
s 和 val
s,或者只支持可为 null 的类型。让我们期待最好的结果吧!