Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to omit lambda parameters in Kotlin?

Tags:

lambda

kotlin

Sometimes I don't use all lambda parameters, like the second parameter in the example below, which is an old value in a change event:

selected.onChange { value, _ ->
    checkBox.isChecked = value
}

How do I omit them? Cause that clutters the code and hurts readability. Previously I used the method above, but in kotlin 1.0.0-beta-1103 underscores are reserved.

like image 805
Yaroslav Avatar asked Oct 30 '15 06:10

Yaroslav


People also ask

How do you pass lambda as parameter Kotlin?

In Kotlin, a function which can accept a function as parameter or can return a function is called Higher-Order function. Instead of Integer, String or Array as a parameter to function, we will pass anonymous function or lambdas. Frequently, lambdas are passed as parameter in Kotlin functions for the convenience.

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.

Can we write parameter less lambda expression?

No, there isn't. Lambda expressions are optimised (in terms of syntax) for the single parameter case. I know that the C# team feels your pain, and have tried to find an alternative. Whether there ever will be one or not is a different matter.

How do you use lambda expression in Kotlin?

A lambda expression is always surrounded by curly braces, argument declarations go inside curly braces and have optional type annotations, the code_body goes after an arrow -> sign. If the inferred return type of the lambda is not Unit, then the last expression inside the lambda body is treated as return value.


2 Answers

As of 1.1, you can do exactly that:

Underscore for unused variables (since 1.1)

If the lambda parameter is unused, you can place an underscore instead of its name:

map.forEach { _, value -> println("$value!") }

https://kotlinlang.org/docs/reference/lambdas.html#underscore-for-unused-variables-since-11

I should add that the compiler now generates a warning for unused lambda parameters, and there's a new corresponding quick fix for Android Studio

like image 54
nvn Avatar answered Sep 18 '22 11:09

nvn


You can use escaping for Java identifiers that are keywords in Kotlin (i.e. backticks) or overload onChange.

Backticks

selected.onChange { value, `_` ->
    checkBox.isChecked = value
}

Overload onChange

interface Listener<T1, T2> {
    fun onChange(f: (T1, T2) -> Unit) // original method
    fun onChange(f: (T1) -> Unit)     // new method
}

And if you cannot change Listener<T1, T2> (or whatever type settable is from your example) then you can use an extension function:

fun <T1, T2> Listener<T1, T2>.onChange(f: (T1) -> Unit) = onChange { t1, t2 -> f(t1) }

You can then call onChange like you want:

selected.onChange { value ->
    checkBox.isChecked = value
}
like image 21
mfulton26 Avatar answered Sep 16 '22 11:09

mfulton26