0

I am new to kotlin, and I have been doing research on the syntax of the language. It is to my understanding that in kotlin you can cast data types using integrated functions like :

.toInt() 

converting 3.14 to an integer :

3.14.toInt()

since it is known that the readline() function returns a string i am not sure why this syntax is correct:

fun main() {
    println("please enter a int:")
    val num1 = readLine()!!.toInt()
    println("one more")
    val num2 = readLine()!!.toInt()

    println("sum : ${num1 + num2}")
}

and this syntax is incorrect

fun main() {
    println("please enter a int:")
    val num1 = readLine().toInt()
    println("one more")
    val num2 = readLine().toInt()

    println("sum : ${num1 + num2}")
}

returns the error:

 Error:(5, 26) Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String

Just looking for a bit more of an explanation on casting and how the syntax differs when it comes to the readline() function and functions alike.

mightyWOZ
  • 7,946
  • 3
  • 29
  • 46
RonsJurisdiction
  • 240
  • 1
  • 2
  • 15

2 Answers2

2

The method readLine() returns a String? - the question mark means it can either be null or a String. In Kotlin, you need to handle instances with nullable type with either ? or !! when you're invoking a method onto that instance.

The difference is that ? only proceeds when the instance is not null, and !! forces it to proceed. The latter may give you a NullPointerException.

For example:

val num1 = readLine()?.toInt()
// Here, num1 could either be a String or null

val num1 = readLine()!!.toInt()
// if it goes to this next line, num1 is not null. Otherwise throws NullPointerException
Christilyn Arjona
  • 2,173
  • 3
  • 13
  • 20
  • Now i understand , so if i got what your saying correctly: readline() returns a string or null which is unacceptable for the .toInt function because it only accepts strings as input ? so by using the !! it automatically declares that num1 isn't of type null – RonsJurisdiction Jan 12 '20 at 02:10
  • @RonComputing Yep that's correct. If `toInt()` also accepts a nullable string, then you don't have to use either `?` or `!!`. You can just invoke it directly with `readLine().toInt()` – Christilyn Arjona Jan 12 '20 at 02:15
1

readLine() returns String? (nullable version of String?) Function toInt() receives String (non-nullable type).

fun String.toInt(): Int   // non-nullable
fun String?.toInt(): Int  // nullable (call)

You must do some kind of a null check to be sure that toInt will called on a non-nullable object. The !! operator converts nullable String? type to non-nullable String.

Timotej Leginus
  • 304
  • 3
  • 18
Leonidos
  • 10,482
  • 2
  • 28
  • 37