为什么Kotlin不进行自动型铸造?

时间:2017-05-20 02:08:21

标签: casting kotlin

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

3 个答案:

答案 0 :(得分:6)

我们都知道Kotlin既有不可为空的Int又有可空的Int?

当我们使用Int?时会发生这种情况:当Kotlin需要一个可以为空的引用时,Kotlin实际上会“封装”JVM原语,因为它旨在消除代码中空引用的危险。

现在看看:(假设这是一个可编辑的代码)

val a: Int? = 1
val b: Long? = a

Kotlin不执行隐式类型转换,因为这件事发生了。如果Kotlin进行隐式类型转换,则b应为1。但由于a是一个装箱的Intb是一个装箱的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())