Kotlin智能强制转换为非空类型和::类语法不能像预期的那样一起工作



我试图理解下面的代码片段(从一个更大的项目中提取)发生了什么,在这个代码片段中,我操作了一个从Java超类返回的值。该值具有类型T,在Java中无界,因此它被映射(我猜)到平台类型T!,我将其视为T?

when (val value = node.getConcentration(molecule)) { // it's a Java method returning an unbounded generic T
is Number -> value.toDouble()
is String -> value.toDouble()
is Time -> value.toDouble()
null -> 0.0 // null has been ruled out, now Kotlin should smart-cast
else -> throw IllegalStateException(
"Expected a numeric value in $molecule at node ${node.id}, " +
"but $value of type ${value::class.simpleName} was found"  // THIS IS THE RELEVANT LINE
)
}

我希望这个工作,但我得到一个错误的类型查找:Expression in a class literal has a nullable type 'T', use !! to make the type non-nullable。在我看来,Kotlin不明白,既然null的情况已被排除,运行时类型必须是Any的子类。

然而,更奇怪的是:

when (val value = node.getConcentration(molecule)) {
is Number -> value.toDouble()
is String -> value.toDouble()
is Time -> value.toDouble()
null -> 0.0 // null has been ruled out, now Kotlin should smart-cast
else -> throw IllegalStateException(
"Expected a numeric value in $molecule at node ${node.id}, " +
"but $value of type ${value!!::class.simpleName} was found" // THIS IS THE RELEVANT LINE
)
}

这个编译,但除了丑陋,这一个提出(正确的,IMHO)一个警告:Unnecessary non-null assertion (!!) on a non-null receiver of type T——但这意味着智能铸造工作如预期!

我目前正在解决以下问题:

when (val value = node.getConcentration(molecule)) { 
is Number -> value.toDouble()
is String -> value.toDouble()
is Time -> value.toDouble()
null -> 0.0
else -> throw IllegalStateException(
"Expected a numeric value in $molecule at node ${node.id}, " +
"but $value of type ${value.let { it::class.simpleName }} was found"
)
}

这个编译时没有警告,总的来说,它是一个可以容忍的样板文件,但是我找不到value::class.simpleName引发错误的任何原因,特别是如果我强制非空性,我得到了预期的警告。

有人明白这是怎么回事吗?这是Kotlin中的一个bug吗?我找不到任何关于这个问题的具体资料(顺便说一下,我是1.4.21)。

您可以尝试像这样更改代码,以分离when语句之外的值的null检查,避免警告,并拥有更干净的代码:

val value = node.getConcentration(molecule)?.let { value ->
when (value) {
is Number,
is String,
is Time -> value.toDouble()
else -> throw IllegalStateException(
"Expected a numeric value in $molecule at node ${node.id}, " +
"but $value of type ${value} was found"
)
}
} ?: 0.0

相关内容

  • 没有找到相关文章

最新更新