I'm starting developing in Android with kotlin and I have a problem with lambdas. I have a function to set a listener in my view, this looks like this:
fun setListener(listener: () -> Unit) {
}
The problem is that the code passed as lambda won't be executed in setListener function, it will be executed in another part of my code (specifically when an item of a spinner is selected) so I have to "save" or "store" this lambda into a variable/property so that I'm able to execute it when needed. Any idea about how to do it?
Edit: I've achieved it by doing:
private var listener: (() -> Unit)? = null
fun setListener(listener: () -> Unit) {
this.listener = listener
}
Is there a better way to do it? Thanks
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.
Creating a Lambda Function The lambda operator cannot have any statements and it returns a function object that we can assign to any variable.
You can assign them to variables and constants just as you can any other type of value, such as an Int or a String . This function takes two parameters and returns the sum of their values. Here, the name of the variable is function and its type is inferred as (Int, Int) -> Int from the add function you assigned to it.
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.
Here's how you can do it:
class Foo {
private var listener: () -> Unit = {}
fun setListener(listener: () -> Unit) {
this.listener = listener
}
}
However, manually writing setters is discouraged in Kotlin. Instead, you can just make your property public:
class Foo {
var listener: () -> Unit = {}
}
For reference, here are the docs about properties with lots of examples.
You can store a function in a property easily. The simplest way:
var listener: (() -> Unit)? = null
Usage:
foo.listener = { println("called") }
If you want your property to be set-only, you can create one public property with unusable getter and one private property for internal use. Full example:
class Example {
// for internal use
private var _listener: (() -> Unit)? = null
// public set-only
var listener: (() -> Unit)?
@Deprecated(message = "set-only", level = DeprecationLevel.ERROR)
get() = throw AssertionError() // unusable getter
set(value) { _listener = value } // write-through setter
fun somethingHappend() {
_listener?.invoke()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With