2016-10-26 13 views
5

私はコトルを学ぼうとしており、参加者は面白く混乱しています。私はJavaクラスでコンストラクタargをとり、Future(IDは別のシステムのリソースを表します)を作成し、Instange変数としてFutureを隠す状況があります。そして、「getXXXメソッドは、」ここFuture.get()将来に委ねるコットリン

を呼び出すと、私は単にそれを構築する方法がわからないですので、私はKotlin例を供給していないのですサンプルJavaクラス

public class Example { 


    private Future<Foo> foo; 

    public Example(String fooId) { 

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

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

です。

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

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

をしかし、Kotlinは、プロパティの振る舞いを一般化するためのより強力な概念がある - the property delegates

答えて

6

あなたはcustom property gettersを使用して簡単な方法でKotlinにJavaコードを変換することができます

class Example { 
    val foo: Foo by someDelegate 
} 

この例では、someDelegateは、プロパティの動作を定義するオブジェクトです。

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

、デリゲートは、プロパティを提供します値は、単にFuture::getから取得されますおそらく、適切な実装がキャンセルと例外処理を処理する必要があります。この目的のために、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) 
} 
+0

オプション2を、私はどこでもこれを繰り返す必要があるため、私は探しています正確に何です。私はこれにスピンを与えるつもりです。 –

+0

私はこの拡張関数を定義すべき興味深い質問を持っています。つまり、それは間違いなくデータクラスに属していません。 –

+0

@ChristianBongiorno、多くのKotlinプロジェクトには 'Utils.kt'または' utils'パッケージが含まれています。プロジェクト全体で拡張機能が使用されている場合、拡張機能がそこに置かれることがよくあります。しかし、拡張子が1つのファイルでローカルに使用されていれば、それを置いて 'private'にしても構いません。 – hotkey