PGMacDesign
PGMacDesign

Reputation: 6312

How to safely cast the result of readLine() to prevent a Type Mismatch using Kotlin

Many Kotlin tutorials I have watched / read have this line of code:

var number = Integer.valueOf(readLine())

And while it clearly worked before, it is now throwing a compiler error while using Android studio and Kotlin version 1.3.50. It indicates a type mismatch where the found is String? and the required is String.

Granted, I understand why this is happening, I get that a user could pass null or empty values in via the console and therefore it needs to have the optional null declaration, but I would like to understand how to fix the compiler error and keep similar code without changing too much.

While I can use both of these lines of code:

var number = Integer.valueOf(readLine()!!)

and

var number = Integer.valueOf(readLine() as String)

I believe those can throw different exceptions as outlined here

I know I am able to 'fix' this problem by using this code:

var number : String? = readLine();
if(number == null){
    number = "0"
}
val number2 = Integer.valueOf(number);

But it seems horribly inefficient. Is there a shorter way to do this using native Kotlin code?

Upvotes: 1

Views: 1240

Answers (3)

You can also put:

var str = readLine().toString();

it works to me!

Upvotes: 0

iamluisg
iamluisg

Reputation: 102

Even though I am primarily a Swift developer, this is a very similar concept. In Swift it is called a nil-coalescing operator, but apparently in Kotlin it is called the Elvis Operator (uh-huh).

The docs are here So your code would look like this:

var num : String = readLine() ?: "0";

If the value before the Elvis operator ?: is not null, it uses that, otherwise it uses the second default value you provide.

Upvotes: 2

Todd
Todd

Reputation: 31710

If we simply call toInt() on the result from readLine(), we will get an exception if the value provided isn't an actual Integer. In order to avoid an exception, we can use toIntOrNull() from the Kotlin Standard Library.

val x= readLine()?.toIntOrNull() ?: 0

In this case, we read the line (as a String?) and if it is non-null, call toIntOrNull() on it. If that is non-null, we have our answer. Otherwise, we use 0 as the default.

Upvotes: 4

Related Questions