Home > OS >  How to understand when I can use a Kotlin anonymous function?
How to understand when I can use a Kotlin anonymous function?

Time:11-14

I'm struggling with Kotlin anonymous functions. The syntax seems to vary (sometimes parenthesis are used, sometimes not) and I'm not sure where they can vs. cannot be used.

In this code for example, what exactly is the anonymous function replacing? It just seems to suddenly pop up in the middle of a builder and it's not at all clear what it's doing.

// Choose between gallery and camera
val builder = AlertDialog.Builder(this)
val sources = arrayOf("Use Camera", "View Gallery")
builder.setItems(sources) { _, which ->
    when (which) {
        0 -> { cameraIntentLauncher.launch(cameraIntent) }
        1 -> { galleryIntentLauncher.launch(galleryIntent) }
        }
    }.create().show(). 

Is it associated with setItems()? Not really. It appears to be defining the callback function that occurs after an item is selected. But there's no ".setCallback()" to attach it to the builder.

In regular Java, I'd expect something like:

builder.setItems(sources, new callbackFunc {...})

But in the above Kotlin, the anonymous function is defined outside of the setItems() parenthesis. It's very confusing.

So what can I read or watch to understand this Kotlin syntax implicitly when reading it?

CodePudding user response:

The concept used here is called Trailing lambdas.

According to Kotlin convention, if the last parameter of a function is a function, then a lambda expression passed as the corresponding argument can be placed outside the parentheses

So your code,

builder
    .setItems(sources) { _, which ->
        when (which) {
            0 -> {
                cameraIntentLauncher.launch(cameraIntent)
            }
            1 -> {
                galleryIntentLauncher.launch(galleryIntent)
            }
        }
    }
    .create()
    .show()

And the below code would be considered as same.

builder
    .setItems(sources, { _, which ->
        when (which) {
            0 -> {
                cameraIntentLauncher.launch(cameraIntent)
            }
            1 -> {
                galleryIntentLauncher.launch(galleryIntent)
            }
        }
    })
    .create()
    .show()
  • Related