Reputation: 23
I have a method which calls an object methods that wants a callback object as parameter. The callback object has to have 2 methods defined, onEvent1() and onEvent2().
One way is to do everything inline, but the result is that it's super-nested and becomes unreadable
myObj.method1(object : baseType {
override fun onEvent1() {
10 lines of nested code
}
override fun onEvent2() {
more nested code
}
)
I found it very unreadable given that a method is more 10 lines.
What is the best way to do this in Kotlin?
The only non-kotlin idiomatic way I know is to declare a class and pass an object of it, maybe inner class.
void mymethod() {
class Obj : baseType {
override fun onEvent1() {....}
override fun onEvent2() {....}
}
val obj : Obj
myObj.method1(obj)
}
Is there a better way?
Upvotes: 2
Views: 104
Reputation: 23091
You could define a helper class that implements the callback type, and accepts the two callback functions (as you suggested):
class Callback(
private val callback1: () -> Unit,
private val callback2: () -> Unit
) : baseType {
override fun onEvent1() = callback1()
override fun onEvent2() = callback2()
}
Then write an extension function to wrap-up the use of the helper class:
fun MyObj.method1(callback1: () -> Unit, callback2: () -> Unit) =
method1(Callback(callback1, callback2))
Then you can call it like this:
myObj.method1({ println("This is callback1") }, { println("This is callback2") })
Alternatively, you could just create an implementation of the callback class:
class Callback : baseType {
override fun onEvent1() {
// 10 lines of nested code
}
override fun onEvent2() {
// more nested code
}
}
And pass an instance of it to method1
:
myObj.method1(Callback())
Upvotes: 2
Reputation: 9944
What if you used two lambdas for the two callbacks? The type of the lambda would be the type for the callback function: in your example () -> Unit
, for a function that takes no arguments and returns a Unit
result. First we make a new method that takes the two callbacks and wraps them up into a single object:
fun myMethod(callback1: () -> Unit, callback2: () -> Unit) {
myObj.method1(object : baseType {
override fun onEvent1() { callback1() }
override fun onEvent2() { callback2() }
})
}
Then we can call the new method like this:
myMethod(
callback1 = { ... },
callback2 = { ... }
)
It's a little more succinct than declaring a new object each time. Another benefit is that we can define the callbacks separately before passing them into the function:
val callback1 = { ... }
val callback2 = { ... }
myMethod(callback1, callback2)
Upvotes: 3