2016-10-26 11 views
5

पर प्रतिनिधिमंडल मैं कोटलिन सीखने की कोशिश कर रहा हूं और प्रतिनिधि दोनों दिलचस्प और भ्रमित हैं। मेरे पास एक ऐसी स्थिति है जहां एक जावा क्लास में मैं एक कन्स्ट्रक्टर तर्क लेता हूं, एक भविष्य बनाता हूं (आईडी किसी अन्य सिस्टम में संसाधन का प्रतिनिधित्व करती है) और भविष्य को एक इंस्टैले वैरिएबल के रूप में छीन लेती है। फिर "getXXX" Future.get()कोटलिन भविष्य में

यहाँ कहेंगे एक नमूना जावा वर्ग

public class Example { 


    private Future<Foo> foo; 

    public Example(String fooId) { 

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

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

मैं Kotlin उदाहरण की आपूर्ति नहीं कर रहा हूँ क्योंकि मैं बस यकीन है कि यह कैसे निर्माण करने के लिए नहीं कर रहा हूँ है।

उत्तर

6

आप custom property getters का उपयोग कर एक सरल तरीके से Kotlin करने के लिए अपने जावा कोड अनुवाद कर सकते हैं:

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

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

लेकिन Kotlin संपत्ति व्यवहार सामान्यीकरण के लिए एक अधिक शक्तिशाली अवधारणा है - the property delegates:

class Example { 
    val foo: Foo by someDelegate 
} 

इस उदाहरण में, someDelegate एक ऐसी वस्तु है जो संपत्ति के व्यवहार को परिभाषित करती है foo

हालांकि Future<V> Kotlin में बॉक्स से बाहर एक प्रतिनिधि के रूप में उपयोग नहीं किया जा सकता है, आप getValue(thisRef, property) और (परिवर्तनशील गुण के लिए) को लागू करने setValue(thisRef, property, value) काम करता है, इस प्रकार स्पष्ट रूप से कोड देकर अपनी स्वयं की संपत्ति प्रतिनिधियों बना सकते हैं जब एक संपत्ति निष्पादित किया जाना है पढ़ा जाता है (और लिखा जाता है, अगर mutable)।

ये फ़ंक्शन या तो आपके प्रोजेक्ट क्लासेस या extension functions के लिए सदस्य फ़ंक्शंस हो सकते हैं, जो Future<V> के साथ केस को फिट करता है। असल में, उदाहरण के लिए, इसके लिए getValue(thisRef, value) विस्तार समारोह को परिभाषित करने के लिए एक संपत्ति प्रतिनिधि के रूप में Future<V> उपयोग करने के लिए, आप है

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

@ क्रिस्टियनबोंगियर्नो, कई कोटलिन परियोजनाओं में 'Utils.kt' या' utils' पैकेज शामिल है, और यदि वे परियोजना में उपयोग किए जाते हैं तो एक्सटेंशन अक्सर वहां रखे जाते हैं। लेकिन यदि एक एक्सटेंशन को एक फ़ाइल में स्थानीय रूप से उपयोग किया जाता है, तो इसे वहां रखना और इसे 'निजी' बनाना ठीक लगता है। – hotkey