Котлин делегирует будущее

Я пытаюсь узнать Котлина, и делегаты интересны и запутанны. У меня есть ситуация, когда в классе java я беру конструктор arg, создаю Будущее (идентификатор представляет ресурс в другой системе) и фиксирует Будущее как переменную instange. Тогда «getXXX» будет называть Future.get()

Вот пример java-класса

 public class Example { private Future<Foo> foo; public Example(String fooId) { this.foo = supplyAsync(() -> httpClient.get(fooId)); } public Foo getFoo() { return foo.get(); } } 

Я не поставляю пример Kotlin, потому что я просто не уверен, как его построить.

Solutions Collecting From Web of "Котлин делегирует будущее"

Вы можете перевести Java-код в Kotlin простым способом с использованием настраиваемых свойств getters :

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

Но у Kotlin есть более мощная концепция для обобщения поведения свойства – делегаты свойств :

 class Example { val foo: Foo by someDelegate } 

В этом примере someDelegate – это объект, определяющий поведение свойства foo .

Хотя Future<V> нельзя использовать в качестве делегата из коробки в Котлине, вы можете создать своих собственных делегатов свойств, реализовав getValue(thisRef, property) и (для изменяемых свойств) функции setValue(thisRef, property, value) , таким образом явно предоставляя код, который будет выполняться при чтении свойства (и записан, если он изменен).

Эти функции могут быть либо функциями-членами для ваших классов проектов, либо функциями расширения , что соответствует случаю с Future<V> . В принципе, для использования Future<V> в качестве делегата свойства вам необходимо определить функцию расширения getValue(thisRef, value) для него, например:

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

Здесь значение, которое делегат предоставит для свойства, будет просто взято из вызова Future::get , но правильная реализация должна, вероятно, позаботиться об обработке отмены и исключениях. С этой целью вы можете перенести Future<V> в класс, который также будет определять резервные значения / стратегии, а затем использовать объекты этого класса.

Затем вы можете использовать объекты Future<V> качестве делегатов для ваших свойств:

 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) }