2016-02-10 9 views
5

में मेमोनाइज़ेशन फ़ंक्शन मेरे पास एक मौजूदा क्लास है जिसमें एक इंस्टेंस विधि बिल्ड है, हाइरार्चरी अनचाहे जिसका हस्ताक्षर नीचे पाया जा सकता है।कोटलिन

private fun buildHierarchyUncached(date: LocalDate): Node { ... } 

मैं एक सार्वजनिक समारोह buildHiearchy buildHierarchyUncached के memoized संस्करण है कि प्रदान करना चाहते हैं।

val buildHiearchy = Memoize<LocalDate, Node>({buildHierarchy(it)}) 

कौन सा की तरह कहा जा सकता है:

hierarchyService.buildHiearchy(businessDate) 

का उपयोग करना:

class Memoize<I, O>(val func: (I) -> O): (I) -> O{ 
    val cache = hashMapOf<I, O>(); 
    override fun invoke(p1: I): O { 
    return cache.getOrPut(p1, { func(p1) }) 
    } 
} 

मैं सक्षम होने के लिए चाहते हैं के रूप में memoized समारोह की घोषणा करने के जो मैं चाहता मैं के करीब प्राप्त कर सकते हैं एक संपत्ति के बजाय एक समारोह, जो एक बड़ा सौदा नहीं है, हालांकि मुझे लगता है कि यह पठनीयता में मदद करता है। इस तरह:

fun buildHierarchy(date: LocalDate): Node = Memoize<LocalDate, Node>({ buildHierarchyUncached(it)}) 

लेकिन यह संकलित नहीं करता है: "मिस्चैच टाइप करें। आवश्यक नोड। ज्ञापन मिला।"

इसके अलावा, यह संकलन क्यों नहीं करता है?

val buildHiearchy = Memoize<LocalDate, Node>({(date) -> buildHierarchy(date)}) 
+0

कंपेलर त्रुटियों वाली चीजों के लिए, कंपाइलर से त्रुटि संदेश शामिल करना अच्छा होता है ताकि अन्य इस SO प्रश्न को खोज/ढूंढ सकें। –

+0

मुझे मिली संकलन त्रुटि जोड़ी गई थी। –

उत्तर

4

समस्या की प्रकृति करके, आप अपने कैश (कैश मूल्य या एक कैशिंग वस्तु या एक प्रतिनिधि) स्टोर करने के लिए एक वर्ग क्षेत्र की जरूरत है। तो आपको कहीं कक्षा में val घोषित करना होगा, क्योंकि कार्य ऐसा नहीं कर सकते हैं।

ध्यान दें कि जब आप अपने buildHiearchy मूल्य की घोषणा, आप एक में दो बातें मिलती है: आप एक वर्ग क्षेत्र में एक Memoize<..>(..) वस्तु की दुकान और आप invoke() समारोह मिलता है (कहीं और की घोषणा की, लेकिन अभी भी ..)। मुझे कोई फर्क नहीं पड़ता कि आप कोई फ़ंक्शन घोषित कर सकते हैं और बिना किसी अतिरिक्त वाक्यविन्यास के फील्ड फ़ील्ड प्राप्त कर सकते हैं।

कोड स्निपेट पुरानी वाक्यविन्यास का उपयोग करता है। इस तरह ठीक करें (कोई कोष्ठक नहीं):

val buildHiearchy = Memoize<LocalDate, Node>({date -> buildHierarchy(date)}) 
+0

एलियास का जवाब बंद करने का उपयोग करता है और उसे कक्षा की आवश्यकता नहीं होती है। आपका स्निपेट मेरे माध्यमिक प्रश्न का उत्तर देता है लेकिन मेरे मुख्य प्रश्न को संबोधित नहीं करता है। मैंने वास्तविक प्रश्न को और स्पष्ट करने के लिए प्रश्न संपादित किया। अर्थात्, कैसे मैं [संपत्ति] संपत्ति के बजाए एक समारोह के रूप में ज्ञात funcion घोषित कर सकते हैं। –

+0

अच्छी तरह से, यह मेरा मुद्दा है - आपके पास कहीं भी – voddan

1

निम्न समाधान एकल-तर्क कार्यों के लिए काम करता है। एक बंद में

val cachedBar = makeFunctionCache({ bar(it) }) 

कार्यान्वयन भंडार कैश ताकि आप एक समर्पित वर्ग में रख की जरूरत नहीं है: आप समारोह का संचित संस्करण बनाया चाहते हैं bar आप बस इसे इस तरह की घोषणा

fun <X, R> makeFunctionCache(fn: (X) -> R): (X) -> R { 
    val cache: MutableMap<X, R> = HashMap() 
    return { 
     cache.getOrPut(it, { fn(it) }) 
    } 
} 
+0

फ़ील्ड के बिना ऐसा फ़ंक्शन नहीं हो सकता है, यह शायद मेरे प्रश्न से स्पष्ट नहीं था। लेकिन मैं कैशबैर को एक समारोह के रूप में घोषित करना चाहता हूं: 'मजेदार कैश्डबार (दिनांक: लोकलडेट): नोड = मेक फ़ंक्शन कैश <लोकलडेट, नोड> ({दिनांक -> बार (दिनांक)}) ' –

+0

क्या आप अपना प्रश्न संशोधित कर सकते हैं और समझा सकते हैं अधिक विस्तार से आपको क्या करना है? यह मुझे स्पष्ट नहीं है कि बंद समाधान क्यों काम नहीं करेगा।ऐसा लगता है, और किसी भी अन्य समारोह की तरह काम करता है। यदि फ़ंक्शन वास्तव में एक इंटरफ़ेस का हिस्सा है तो भिन्नताएं हैं, लेकिन अधिक जानकारी उपयोगी होगी। –