var a : Double
a = Math.sin(10) // error: the integer literal does not conform to the expected type Double
a = Math.sin(10.0) //This compiles successfully
println(a)
为什么kotlin不执行隐式类型转换并强制我们传递确切的数据类型?
fun sin(value: Double): Double // at kotlin documentation
答案 0 :(得分:6)
我们都知道Kotlin既有不可为空的Int
又有可空的Int?
。
当我们使用Int?
时会发生这种情况:当Kotlin需要一个可以为空的引用时,Kotlin实际上会“封装”JVM原语,因为它旨在消除代码中空引用的危险。
现在看看:(假设这是一个可编辑的代码)
val a: Int? = 1
val b: Long? = a
Kotlin不执行隐式类型转换,因为这件事发生了。如果Kotlin进行隐式类型转换,则b
应为1
。但由于a
是一个装箱的Int
而b
是一个装箱的Long
, a == b
会产生false
并跌倒矛盾,因为==
运算符检查equals()
和Long
的{{1}}检查其他部分也是equals()
。
查看文档:
答案 1 :(得分:3)
Kotlin不允许隐式转换数字类型。有一种误解认为隐性转换是“没有伤害,没有犯规”......这是错误的。
Java中用于隐式转换的过程比您想象的更复杂,read the docs以查看所有内容。然后你可以尝试分析所有可能出错的案例。
Kotlin,不希望编译器猜测你的意图,因此它使语言中的所有内容都明确,包括数字类型转换。正如在Explicit Conversions的Kotlin文档中所解释的那样,它清楚地说明了:
由于表示不同,较小的类型不是较大类型的子类型。 [...] 因此,较小的类型不会隐式转换为更大的类型。 [...] 我们可以使用显式转换来扩大数字。
文档显示了一个可以解决问题的样本,但还有很多其他问题。
也不能只将一种数字类型转换为另一种数字类型,如此处所提及的错误评论和答案中所述。这只会导致一个很好的运行时错误。而是查看数字转换函数,例如数字类型上的toInt()
和toDouble()
,例如Number class上的。{/ p>
明确性是Kotlin人格的一部分,并没有计划改变。
答案 2 :(得分:2)
数字类型的自动类型转换会导致精度下降。请考虑以下java代码:
double hoursSinceUnixEra = System.currentTimeMillis()/1000/60/60;
目的不是将结果缩短到整个小时,尽管它在Java中没有任何警告就编译。
val hoursSinceUnixEra = System.currentTimeMillis()/1000/60/60;
someObject.doubleValue = hoursSinceUnixEra
以上Kotlin代码将因为无法显示而无法编译。
这种类型的问题可能很难找到并修复,这就是这个决定背后的原因。 您仍然可以显式转换类型:
val value = 3
Math.sin(value.toDouble())