Why doesn't Kotlin perform automatic type-casting?

心不动则不痛 提交于 2020-01-21 07:23:12

问题


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)

Why doesn't kotlin perform implicit type conversion and force us to pass the exact type of data?

fun sin(value: Double): Double // at kotlin documentation

回答1:


We all know that Kotlin has both non-nullable Int and nullable Int?.

When we use Int? this happens: Kotlin actually 'boxes' JVM primitives when Kotlin needs a nullable reference since it's aimed at eliminating the danger of null references from code.

Now look at this: (assuming this is a compilable code)

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

Kotlin doesn't perform implicit type conversion because of this thing happens. If Kotlin did implicit type conversions, b should be 1. but since a is a boxed Int and b is a boxed Long, a == b yields false and falls into contradiction, since its == operator checks for equals() and Long's equals() checks other part to be Long as well.

Check the documentation:

  • Explicit Conversions in Kotlin
  • https://kotlinlang.org/docs/reference/basic-types.html
  • https://kotlinlang.org/docs/reference/equality.html



回答2:


Kotlin does not allow implicit conversions of numeric types. There is a misconception that implicit conversions are "no harm, no foul" ... which is wrong.

The process in Java for implicit conversions is more complicated than you think, read the docs to see what all is entailed. And then you can try to analyze all of the cases that can go wrong.

Kotlin, does not want the compiler to guess as to your intention, so it makes everything in the language explicit, including numeric type conversions. As explained in the Kotlin docs for Explicit Conversions it says clearly:

Due to different representations, smaller types are not subtypes of bigger ones. [...] As a consequence, smaller types are NOT implicitly converted to bigger types. [...] We can use explicit conversions to widen numbers.

And the documentation shows one such sample of where things can go wrong, but there are many others.

Nor can you just cast one numeric type to another, as mentioned here in incorrect comments and answers. That will only result in a nice runtime error. Instead look at the numeric conversion functions such as toInt() and toDouble() found on the numeric types, such as on the Number class.

Explicitness is part of the Kotlin personality, and it is not planned to change.




回答3:


Automatic type casting for numeric types can lead to losing precision. Just consider following java code:

double hoursSinceUnixEra = System.currentTimeMillis()/1000/60/60;

The intention was not to cut the result to full hours, although it compiles without any warning in Java.

val hoursSinceUnixEra = System.currentTimeMillis()/1000/60/60;
someObject.doubleValue = hoursSinceUnixEra

Above Kotlin code won't compile due to unexplicit casting.

Issue of this type can be very hard to find and fix and it's the reason behind this decision. You can still explicitly convert type:

val value = 3
Math.sin(value.toDouble())


来源:https://stackoverflow.com/questions/44081233/why-doesnt-kotlin-perform-automatic-type-casting

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!