2016-10-26 54 views
5

Kotlin'i öğrenmeye çalışıyorum ve delegeler ilginç ve kafa karıştırıcı. Bir java sınıfında ben bir kurucu argüman alacağım, bir Gelecek (ID başka bir sistemde bir kaynağı temsil ediyor) ve Geleceği bir instange değişkeni olarak saklayacağım bir durumum var. Ardından "getXXX" İşte Future.get()Kotlin geleceğe delege veren

çağırır örnek bir java sınıfı

public class Example { 


    private Future<Foo> foo; 

    public Example(String fooId) { 

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

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

Ben sadece bunu nasıl oluşturulacağı emin değilim çünkü Kotlin örneğini temin değilim olduğunu.

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

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

Ama Kotlin mülkiyet davranışını genelleme için daha güçlü bir kavram var - the property delegates:

cevap

6

Sen custom property getters kullanarak basit bir şekilde KOTLIN için Java kodu çevirebilir

class Example { 
    val foo: Foo by someDelegate 
} 

Bu örnekte, someDelegate, özelliğin davranışını tanımlayan bir nesnedir foo.

rağmen Future<V> KOTLIN içinde kutunun dışında bir temsilci olarak kullanılamaz, ne zaman bir özellik yürütülecek açıkça böylece setValue(thisRef, property, value) fonksiyonları (değişebilir özellikleri için) getValue(thisRef, property) ve uygulama kodunu belirtip kendi mülkiyet delegelere oluşturabilir okunabilir (ve değiştirilebiliyorsa yazılmış).

Bu işlevler, proje sınıflarınız veya extension functions için Future<V> numaralı duruma uyan üye işlevleri olabilir. Temelde, örneğin, bunun için getValue(thisRef, value) uzatma fonksiyonunu tanımlamak için bir özellik delege olarak, siz gelmiş Future<V> kullanmak: Burada

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

, temsilci bir özellik için sağlayacaktır değeri basitçe Future::get alınacak çağrı, ancak uygun bir uygulama muhtemelen iptal ve istisnaların ele alınması gerekir. Bu amaçla, Future<V>'u geri dönüş değerlerini/stratejilerini de tanımlayacak bir sınıfa sarın ve sonra bu sınıfı 'nesnelerini by'da kullanabilirsiniz.

Sonra da özellikleri için delege olarak Future<V> nesneleri kullanabilirsiniz:

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

Seçenek 2 Ben her yerde bu tekrarlamanız gerekir, çünkü aradığım tam olarak ne olduğunu. Bunu bir spin vereceğim. –

+0

Bu uzantı işlevini tanımlamam gereken ilginç bir soru var. Demek istediğim, kesinlikle bir veri sınıfına ait değil. –

+0

@ChristianBongiorno, pek çok Kotlin projesi 'Utils.kt' veya' utils' paketini içerir ve uzantılar genellikle proje genelinde kullanılırsa yerleştirilir. Ancak bir uzantı tek bir dosyada yerel olarak kullanılıyorsa, oraya koymak ve özel yapmak için iyi görünüyor. – hotkey