Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The lambda expression is unused

While using Android's Switch, I was attaching a setOnCheckedChangeListener to it and got this warning

The lambda expression is unused. If you mean a block, you can use 'run {...}'

Here' the code snippet:

switchAction.setOnCheckedChangeListener({
    _, isChecked ->
    {
        preferences.userStatus = isChecked
        switchToggleVisibility(isChecked)
        if (isChecked) {
            fetchStats()
            getOrders()
        } else {
            releaseOrder()
        }
    }
})

Using run does fix this warning, but does anyone know the cause behind this? How is the lambda expression unused?

like image 467
Prithvi Bhola Avatar asked Jul 21 '17 07:07

Prithvi Bhola


People also ask

What are lambda expressions in Kotlin?

Lambda expression is a simplified representation of a function. It can be passed as a parameter, stored in a variable or even returned as a value. Note: If you are new to Android app development or just getting started, you should get a head start from Kotlin for Android: An Introduction.

What is trailing lambda in Kotlin?

To help deal with this, Kotlin supports a specific kind of syntax referred to as trailing lambda syntax. This syntax states that if the final parameter to a function is another function, then the lambda can be passed outside of the function call parentheses.

How do I return from lambda Kotlin?

Just use the qualified return syntax: return@fetchUpcomingTrips . In Kotlin, return inside a lambda means return from the innermost nesting fun (ignoring lambdas), and it is not allowed in lambdas that are not inlined. The return@label syntax is used to specify the scope to return from.


2 Answers

You're mixing Java's lambda notation with Kotlin's lambda notation, creating a lambda that returns another nested lambda in this case. The correct and idiomatic syntax would look like this:

switchAction.setOnCheckedChangeListener { _, isChecked ->     preferences.userStatus = isChecked     switchToggleVisibility(isChecked)     if (isChecked) {         fetchStats()         getOrders()     } else {         releaseOrder()     } } 

Taking all the noise out, a normal lambda looks like this:

{ arg1, arg2 -> returnValue } // Type: (A, B) -> C 

You did this:

{ arg1, arg2 -> { returnValue } } // Type: (A, B) -> (() -> C) 

Which could also be written like this:

{ arg1, arg2 -> { -> returnValue } } // Type: (A, B) -> (() -> C) 

This notation makes it a bit clearer that the lambda doesn't return the return value, but returns another lambda with no parameters that returns the return value.

Usually, this would get caught by the compiler as a wrong return type, but in your case, the return value of the lambda is not used. So, you're just creating the inner lambda without returning or running it, that's why you're getting a warning.

like image 122
Robin Avatar answered Sep 16 '22 13:09

Robin


Yes, the

_, isChecked ->     { ... } 

Must be changed to

_, isChecked ->     preferences.userStatus = isChecked     switchToggleVisibility(isChecked)     if (isChecked) {         fetchStats()         getOrders()     } else {         releaseOrder()     } 

So just remove the curly braces because else you just create a block which isn't executed at all. Alternatively you could also do

_, isChecked ->     run {         preferences.userStatus = isChecked         switchToggleVisibility(isChecked)         if (isChecked) {             fetchStats()             getOrders()         } else {             releaseOrder()         }     } 
like image 32
guenhter Avatar answered Sep 16 '22 13:09

guenhter