How to improve kotlin lambda syntax?

I'm trying to use kotlin M12 in an android project, and while working I got this part of the code to subscribe ({onSuccess (it)}, {onFailure (it)})

AppObservable.bindActivity(this, api.get(id)).subscribe({onSuccess(it)}, {onFailure(it)}) fun onSuccess(str: String) {} fun onFailure(tr: Throwable) {} 

This is not so bad, but I think it will / should be better. How can I improve it?

+5
source share
1 answer

First, create a helper extension method as follows:

 fun<T, R> Observable<T>.subscribe( receiver: R, onSuccess: R.(T) -> Unit, onFailure: R.(Throwable) -> Unit) { subscribe({ receiver.onSuccess(it) }, { receiver.onFailure(it) }) } 

Now you can use your new method as follows:

 AppObservable.bindActivity(this, api.get(id)).subscribe(this, ::onSuccess, ::onFailure) 

The :: operator creates a reference to the method. Once KT-6947 is enabled, we can omit the helper method and write subscribe(this::onSuccess, this::onFailure) directly. This is already possible in Java 8.

To work around this problem, we can alternatively implement the following helper method, which binds the receiver to the extension method:

 fun <T, R, E> T.bind(reference: T.(R) -> E): (R) -> E = { this.reference(it) } 

and use it as follows:

 AppObservable.bindActivity(this, api.get(id)).subscribe(bind(Foo::onSuccess), bind(Foo::onFailure)) 

but it is a little more elegant than your original decision.

EDIT1:

The syntax is your ::onSuccess now prohibited, so you need to use "Foo :: onSuccess", where Foo is your class name.

EDIT2:

You can have some fun while overloading the statement by declaring the same method as

 operator fun <T, R, E> T.plus(reference: T.(R) -> E): (R) -> E = { this.reference(it) } 

Then you can use it like this:

 AppObservable.bindActivity(this, api.get(id)).subscribe(this + Foo::onSuccess, this + Foo::onFailure) 
+6
source

All Articles