Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin delegating to a future

Tags:

java

kotlin

I am trying to learn Kotlin and delegates are both interesting and confusing. I have a situation where, in a java class I would take a constructor arg, create a Future (the ID represents a resource in another system) and stash the Future as an instange variable. Then the "getXXX" would call Future.get()

Here is a sample java class

public class Example {


     private Future<Foo> foo;

     public Example(String fooId) {

        this.foo = supplyAsync(() -> httpClient.get(fooId));
     }

     public Foo getFoo() {
      return foo.get();
     }
}

I am not supplying the Kotlin example because I am simply not sure how to construct it.

like image 884
Christian Bongiorno Avatar asked Oct 26 '16 21:10

Christian Bongiorno


People also ask

How does kotlin delegate work?

So a delegate is just a class with two methods: for getting and setting value of a property. To give it some more information, it is provided with the property it's working with via the instance of KProperty class, and an object that has this property via thisRef . That's it!

What is property delegation?

Delegating to another propertyA property can delegate its getter and setter to another property. Such delegation is available for both top-level and class properties (member and extension). The delegate property can be: A top-level property. A member or an extension property of the same class.

What is a delegate Android?

Delegated apps are apps that receive additional capabilities from the profile owner or device owner apps. Some of these capabilities involve the framework calling into the apps. To receive these callbacks, delegated apps should subclass this class and override the appropriate methods here.


1 Answers

You can translate your Java code to Kotlin in a straightforward way using custom property getters:

class Example(fooId: Int) {
    private val fooFuture = supplyAsync { httpClient.get(fooId) }

    val foo: Foo
        get() = fooFuture.get()
}

But Kotlin has a more powerful concept for generalizing property behavior -- the property delegates:

class Example {
    val foo: Foo by someDelegate
}

In this example, someDelegate is an object that defines the behavior of property foo.

Though Future<V> cannot be used as a delegate out of the box in Kotlin, you can create your own property delegates by implementing getValue(thisRef, property) and (for mutable properties) setValue(thisRef, property, value) functions, thus explicitly providing the code to be executed when a property is read (and written, if mutable).

These functions can be either member functions for your project classes or extension functions, which fits the case with Future<V>. Basically, to use Future<V> as a property delegate, you have to define the getValue(thisRef, value) extension function for it, for example:

operator fun <V> Future<V>.getValue(thisRef: Any?, property: KProperty<*>) = get()

Here, the value the delegate will provide for a property will be simply taken from the Future::get call, but a proper implementation should probably take care of cancellation and exceptions handling. For this purpose, you can wrap a Future<V> into a class that will also define the fallback values/strategies, and then use this class' objects in by.

Then you can use Future<V> objects as delegates for your properties:

class Example(fooId: Int) {
    val foo: Foo by supplyAsync { Thread.sleep(2000); fooId }
}

fun main(args: Array<String>) {
    val e = Example(123)
    println(e.foo)
}
like image 175
hotkey Avatar answered Oct 03 '22 09:10

hotkey