2013-02-08 19 views
6

मैं एक विकल्प के रूप में एक विधि को बंद करना चाहता हूं और मैं नीचे दिखाया गया हूं। मुझे नीचे दिखाए गए संकलन त्रुटि मिलती है। क्या किसी फ़ंक्शन में वैकल्पिक क्लोजर पैरामीटर पास करना संभव है?फ़ंक्शन में वैकल्पिक क्लोजर पैरामीटर कैसे पास करें?

def sampleMethod(a: String, b: String, optionalMethod: Option[(String, Int) => Unit]) { 
    // do some processing with a and b 
    optionalMethod match { 
     case Some(optionalMethod) => { 
     optionalMethod("a",3) 
     } 
     case _ 
     log("no optional method passed") 
    } 
} 

// definition of optMethod in some other place 
val optMethod = (c: String, d: Int) => { 
    // some processing with c, d and external values 
} 

// invoke 
sampleMethod("hi", "bye", optMethod) => FAILS TO COMPILE 

ERROR = type mismatch. expecting Option[(String, Int) => Unit] found (String, Int) => Unit 
+0

नमूना विधि ("हाय", "अलविदा", कुछ (optMethod)) – twillouer

+0

वैकल्पिकMethod.map (f => f ("a", 3)) अधिक स्पष्ट होने के लिए – twillouer

+1

बस 'अन्य भाषाओं और उनके उपयोगकर्ता समुदाय के साथ मैला termino लॉजी, चलो यहाँ ऐसा नहीं करते हैं। "क्लोजर" का मतलब फ़ंक्शन शाब्दिक (उस फ़ंक्शन के शरीर में बाइंडिंग के बिना नाम) में नि: शुल्क चर के उपयोग को संदर्भित करता है और उन संदर्भों को शब्दावली वातावरण में "बंद" किया जाता है। सभी कार्यों में व्याख्यात्मक वातावरण में बंद होना शामिल नहीं है। सभी कार्य फ़ंक्शन अक्षर नहीं हैं। उदाहरण के लिए, वे अक्सर किसी अन्य फ़ंक्शन या विधि के "आंशिक अनुप्रयोग" के माध्यम से (या तो संकलक या स्पष्ट रूप से पारदर्शी रूप से और पारदर्शी रूप से) बनाए जाते हैं। –

उत्तर

3

कैसे

के बारे में
sampleMethod("hi", "bye", Some(optMethod)) 
6

जैसा कि पहले बताया, अपने विधि optionalMethod युक्त एक Option मूल्य की उम्मीद है। आप इसलिए यह करने के लिए एक Option मान पास करना होगा:

// invoke with method 
sampleMethod("hi", "bye", Some(optMethod)) 
// invoke without method 
sampleMethod("hi", "bye", None) 

आप Option मूल्य से बचना चाहते हैं, तो आपको निम्न कोशिश कर सकते हैं (खासकर None से बचें।):

def sampleMethod(a: String, b: String, optionalMethod: (String, Int) => Unit = (_, _) => log("no optional method passed")) { 
    optionalMethod("a", 3) 
} 

// invoke with method 
sampleMethod("hi", "bye", optMethod) 
// invoke without method 
sampleMethod("hi", "bye") 
0

अधिक स्पष्ट:

scala> def sampleMethod(a: String, b: String, optionalMethod: Option[(String, Int) => Unit]) { 
    | optionalMethod.map(f => f("a", 3)) 
    | } 
sampleMethod: (a: String, b: String, optionalMethod: Option[(String, Int) => Unit])Unit 


scala> sampleMethod("A", "A", Some((c:String, d:Int) => println(s"Hello wolrd $c...$d"))) 
Hello wolrd a...3 

तुम बस को जोड़ना होगा "कुछ()" अपने optinal समारोह के आसपास

7

त्रुटि संदेश बहुत स्पष्ट है: sampleMethodOption की अपेक्षा करता है, लेकिन आप सीधे फ़ंक्शन मान पास कर रहे हैं (Some में लपेटा नहीं गया है)।

इसे ठीक करने का सबसे सरल तरीका एक Some में optMethod रैप करने के लिए है:

sampleMethod("hi", "bye", Some(optMethod)) 

लेकिन बस sampleMethod("hi", "bye", optMethod) करते हैं, आप अतिभारित जोड़ सकता है अगर आप में सक्षम होना चाहते sampleMethod की परिभाषा:

object Test { 
    def sampleMethod(a: String, b: String, optionalMethod: Option[(String, Int) => Unit]) { 
    // do some processing with a and b 
    optionalMethod match { 
     case Some(optionalMethod) => { 
     optionalMethod("a",3) 
     } 
     case _ => log("no optional method passed") 
    } 
    } 
    def sampleMethod(a: String, b: String) { sampleMethod(a, b, None) } 
    def sampleMethod(a: String, b: String, optionalMethod: (String, Int) => Unit) { 
    sampleMethod(a, b, Some(optionalMethod)) 
    } 
} 

val optMethod = (c: String, d: Int) => { 
    // some processing with c, d and external values 
} 

// invoke 
Test.sampleMethod("hi", "bye", optMethod) // Now Compiles fine 
Test.sampleMethod("hi", "bye") // This too 
+0

मुझे लगता है कि फ़ंक्शन तर्क के लिए 'विकल्प' का उपयोग करने से ओवरलोडिंग एक बेहतर तरीका है। –

+0

आपका मतलब है कि मेरे जवाब में 3 ओवरलोड के विपरीत केवल 2 अधिभार (तर्क के साथ एक और बिना) का उपयोग करना है? यदि ऐसा है, तो बात यह है कि सामान्य मामले में दोनों मामलों के बीच पर्याप्त सामान्य व्यवहार हो सकता है जिसे आप एक ही कार्यान्वयन में कारक बनाना चाहते हैं (जैसा कि मेरे पहले अधिभार में सभी काम करता है), और पर्याप्त मतभेद जो केवल 'वैकल्पिक विधि 'के लिए डिफ़ॉल्ट मान (जैसे @ fynn के उत्तर में) पर्याप्त नहीं हो सकता है। यह वास्तविक जरूरतों पर निर्भर करता है। –

+2

फिर एक निजी विधि बनाएं जो काम करता है और 'विकल्प [फंक्शन]' लेता है जिसे तब 'फंक्शन' के साथ और बिना ओवरलोड किए गए सार्वजनिक तरीकों से बुलाया जाता है। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^