Saturday 11 February 2017

Kotlin Literals 2

So in the previous post we have seen that Kotlin only supports positive integer literals, which means that half the numbers it supports can't be written as a literal in code. Let's look at other ways to write number literals, maybe as hexadecimal. This is for example used often for Android colors:
val green: Int = 0xff00ff00
This code looks good, right? Android colors use a 4 byte ARGB format, and the above number matches that and would work fine in Java. Well, again, it doesn't work in Kotlin. The compiler gives again a unhelpful message:
The integer literal does not conform to the expected type
What does that mean? It turns out that Kotlin again only supports positive number literals. 0xff00ff00 would be negative when written as a signed integer and so Kotlin thinks this should be a Long. The unnecessarily complicated and ugly solution:
val green = 0xff00ff00.toInt() // Explicit cast to Int
Do you want to do that every time you write down a color ? I don't.

And again, the problem is worse for Long values. Try to write 0xff00ff00ff00ff00 as literal. Doesn't work. As there is no larger type that could be downcast as above, you are really out of options here. Jetbrains recommends the following workaround:
val foo: Long = java.lang.Long.parseUnsignedLong("ff00ff00ff00ff00", 16)
which requires Java 8 and is so ugly, I don't even know what to say.

The good thing is, that Jetbrains is aware of the problems and seems to want to fix this by introducing unsigned types and other improvements.

In the future, I might add a post about String and floating point literals.

No comments:

Post a Comment