Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Kotlin elvis operator don't work with map.get()

meet some strange behaviour of Kotlin elvis operator, when try get some value by key from map, and no one of the blocks is not execute.

map["Key"]?.let {
    println("Run block, inserting into existing list")
    it.add("value")
} ?: {
    println("Elvis block, creating list with value")
    map["Key"] = mutableListOf("value")
}

I expect, that if Key is exist, it going execute let block, print line and insert value into existing list. If key is not exist, it going to elvis block, print line, and insert new list with value.
But it’s not. As not let block as being execute, not elvis.

To solve my task i using:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

map.getOrPut("Key") { mutableListOf() }.add("Value")

Question is, why i can’t just use elvis with let operator in that situation?

Kotlin version 1.8.22

>Solution :

The expression you put on the left hand side of ?: is:

{
    println("Elvis block, creating list with value")
    map["Key"] = mutableListOf("value")
}

This is just a lambda of type () -> Unit. Evaluating this expression just gives you a value of type () -> Unit. The code in the block is not executed.

You should use run if you want to execute the code in the lambda:

map["Key"]?.let {
    println("Run block, inserting into existing list")
    it.add("value")
} ?: run {
    println("Elvis block, creating list with value")
    map["Key"] = mutableListOf("value")
}

That said, something simple like this is more readable, if you want to print different messages depending on whether the key exists:

val list = map["Key"]
if (list != null) {
    println("Run block, inserting into existing list")
    list.add("value")
} else {
    println("Elvis block, creating list with value")
    map["Key"] = mutableListOf("value")
}

Of course, if you don’t need to print different messages, the idiomatic way is getOrPut.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading