Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert Any to Int in Kotlin

Tags:

I have an attribute in my model defined as above that in some cases contain an Int.

var value: Any? 

I know that I can do it if I cast first to String and then to Int

value.toString().toInt() // works 

Is there a way of doing it by skipping casting into a String before? When I try to cast directly to into an Int I get this error

FATAL EXCEPTION: main java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer 
like image 818
pablobu Avatar asked May 09 '17 18:05

pablobu


People also ask

How do you int in Kotlin?

To convert a string to integer in Kotlin, use String. toInt() or Integer. parseInt() method. If the string can be converted to a valid integer, either of the methods returns int value.


2 Answers

The problem is that you were attempting to cast directly from a String to an Int with value as Int.

This isn't working because, as the exception is telling you, value contains a String, and a String cannot be coerced into an Int. The fact that this String represents an integer doesn't matter, as it would need to be parsed into an Int. That precisely is what the toInt() method does.

The reason you must cast to a String first is because toInt() is an extension method on String, and value is of type Any?. This means that you can't call toInt() directly on value because it doesn't know that it contains a String at compile time, even though it does at runtime. If you wanted to skip this step, you could also use smart casts by checking the type first:

if (value is String) {     value.toInt() } 

You can find a bit more info on smart casts and other Kotlin type casting here: https://kotlinlang.org/docs/reference/typecasts.html#smart-casts

This also may be pointing to an underlying design problem. You expect that this will sometimes contain an Int, but as we can see here whatever is setting this value in your model is setting it to a String containing that number. Do you expect this value to truly be able to contain many different types, or are you only expect Int and String? If the latter, then it would possibly be a better design decision to make this a String rather than an Any?. That would prevent unexpected/unhandled types from being provided, and make the model less ambiguous to anyone looking at or using it.

like image 55
PseudoPsyche Avatar answered Oct 26 '22 19:10

PseudoPsyche


This is the way I do it:

val myInt = value as? Int ?: defaultValue

This will try to convert value to an int, but if it fails, will use defaultValue instead.

like image 28
Mick Avatar answered Oct 26 '22 19:10

Mick