科特林委托未来

Chr*_*rno 5 java kotlin

我正在努力学习Kotlin,代表们既有趣又令人困惑.我有一种情况,在java类中,我将采用构造函数arg,创建一个Future(ID表示另一个系统中的资源)并将Future存储为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();
     }
}
Run Code Online (Sandbox Code Playgroud)

我没有提供Kotlin示例,因为我根本不确定如何构建它.

hot*_*key 6

您可以使用自定义属性getter以简单的方式将Java代码转换为Kotlin :

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

    val foo: Foo
        get() = fooFuture.get()
}
Run Code Online (Sandbox Code Playgroud)

但Kotlin有一个更强大的概念来概括财产行为 - 财产代表:

class Example {
    val foo: Foo by someDelegate
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,someDelegate是一个定义属性行为的对象foo.

虽然Future<V>不能在Kotlin中作为开箱即用的委托使用,但您可以通过实现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()
Run Code Online (Sandbox Code Playgroud)

在这里,委托将为属性提供的值将简单地从Future::get调用中获取,但正确的实现应该可以处理取消和异常处理.为此,您可以将a包装Future<V>到一个类中,该类也将定义回退值/策略,然后使用此类的对象by.

然后,您可以将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)
}
Run Code Online (Sandbox Code Playgroud)