Leonardo Pascotto
Leonardo Pascotto

Reputation: 13

Incomplete code with Elvis operator and addition in Kotlin

I am learning Kotlin and I happened to write this:

 var nullTest: Int? = null
 println(nullTest?++ ?:0)

Trying to compile and run, I get the "incomplete code" error. Same with:

 var nullTest: Int? = null
 println(nullTest?+1 ?:0)

While if I use:

var nullTest: Int? = null
println(nullTest?.inc() ?:0)

It compiles and runs correctly. Why is that so? Why do I have to use .inc() and can't I just use the + operator?

Thank you

Upvotes: 1

Views: 321

Answers (3)

Oskar Kielczyk
Oskar Kielczyk

Reputation: 26

You can only use "++" incrementation and "--" decrementation on non nullable variables. Same rule to operators like "+", "-", "/", "*", etc.

If you have nullable variable you have to use translated methods like ".plus()", ".minus()", ".div()", ".inc()", ".dec()", with '?' before dot of course.

Upvotes: 0

Benjamin Charais
Benjamin Charais

Reputation: 1368

The safe call operator in Kotlin is represented as ?. and is not referenced in any other manner. The Elvis operator works similar to a != null check but will resolve to the right side if the left is null similar to how

val thing: Int? = null
val other: Int = 42

val new: Int = if (thing != null) thing else other

One of the ways to make it easier to understand this, is it all comes down to function signatures at the end of the day. From Kotlin Functions

A function signature is a unique identification of a function for the Kotlin compiler. The signature consists of a function name, its parameters, and the return type.

Any operator function such as the +, ++, or - has a correlated function name, but is a special syntax for writing that function reference. Operator Function Overloads

The operator overload functions don't have a syntax for handling the safe null call before themselves being called. The safe call may only be called on a . operator.

From your example

var nullTest: Int? = null
println(nullTest?+1 ?:0)

If we need an operation and the null check, we would have to do like I showed above with the if statement, otherwise we have to split the operations to multiple lines

var nullTest: Int? = null
var backup = 0

// This adds one to the values regardless of if it was null or not
val ourValue = (nullTest ?: backup) + 1

// Uses safe call operator to only increment the nullable value
val otherValue = nullTest?.inc() ?: backup

println(ourValue)
println(otherValue)

Or we can do this with an if and only add one to the potentially null value

var nullTest: Int? = null
var backup = 0

// Only adds one to the nullable value
val ourValue = if (nullTest != null) nullTest + 1 else backup

println(ourValue)

Upvotes: 0

gidds
gidds

Reputation: 18547

nullTest?.inc() works because ?. is an operator: the safe-call operator, which calls the following function only if the value is not null.

nullTest?++ doesn't mean anything in Kotlin, because ? on its own doesn't mean anything; there's no lone ? operator.  (Also, ++ needs to follow the name of a variable or property it can increment.  Similarly, + needs to be between two values.)

Upvotes: 1

Related Questions