1

for example:

var str: String? = null
str ?: null

When ran returns null, but which one? I don't foresee any practical purpose for this - I'm just curious.

MDJ
  • 63
  • 1
  • 1
  • 5
  • Possible duplicate of [What does ?: do in Kotlin?](https://stackoverflow.com/questions/48253107/what-does-do-in-kotlin) – Makoto May 11 '18 at 21:20
  • @Makoto to be clear, I'm aware what the operator does. The 'explicit-ness' of it, however, was not until Todd's answer. – MDJ May 11 '18 at 21:49
  • [You mean that this answer wasn't explicit?](https://stackoverflow.com/a/48253176/1079354) – Makoto May 11 '18 at 21:50
  • You're right. Looking back, it seems so obvious now. I think what confused me is that I had assumed the elvis operator was intended to convert nullable types into non-nullable types (wherein my question would have been justified, though unlikely to have not been asked before). If it turns out this is a duplicate question and gets removed, that's ok. My curiosity was slaked and I learned something. That's a win. Have a great @Makoto! – MDJ May 11 '18 at 21:58
  • Glad it helped! You can actually accept the duplicate and close the question yourself if you want to (closing the question doesn't do anything _negative_ per se; just prevents others from answering when we already have an answer elsewhere). – Makoto May 11 '18 at 22:34

2 Answers2

2

The elvis operator works like this: If the left operand evaluates to null, the right operand gets used. See this answer.

In your case, the right null gets chosen but it's totally useless to use it like this. Using the elvis operator only makes sense if you provide non-null alternatives to the corresponding left operand.

s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
  • Also a great answer. I chose @Todd's answer as the winner because I found that the code he wrote did a bang up job of illustrating his point. I still gave you an uptick though, which wont get reflected here as i have less than 15 rep points. Hoping it still reflects on your total rep points - if not, sorry man I tried... – MDJ May 11 '18 at 21:46
2

The answer you are looking for is the right hand side value, which is exactly what we would expect. The fact that both of them are null has no bearing on the order in which they are evaluated, Kotlin has a contract and sticks to it.

If I type your code in my editor, I get a warning that "Right operand of elvis operator (?:) is useless if it is null", which seems correct to me. In order to get around that, let's replace the left AND right hand sides with functions that return null instead...

fun alwaysReturnsNull(log: String): String? {
    println(log)
    return null
}

val str: String? = alwaysReturnsNull("first") ?: alwaysReturnsNull("second")
println(str)

In this case, the output is "first" followed by "second", showing that Kotlin is evaluating these function values in the order you'd expect: left hand of elvis, and then right hand of elvis.

Todd
  • 30,472
  • 11
  • 81
  • 89
  • 1
    Aha! The first is evaluated as null and is therefor not used. Period. Leaving the second as the only candidate. Thanks for clearing that up. My curiosity is satisfied! – MDJ May 11 '18 at 21:40