2012-10-07 10 views
17

मैं कुछ तरीकों एक अंतर्निहित पैरामीटर लेने के साथ एक वर्ग को परिभाषित करने के लिए कोशिश कर रहा हूँ:कैसे श्रेणी स्तर पर निहित मापदंडों के लिए डिफ़ॉल्ट मान प्रदान करने के लिए

object Greetings { 
    def say(name: String)(implicit greetings: String): String = greetings + " " +name 
} 

मैं किसी अन्य वर्ग से इस वर्ग का उपयोग

implicit val greetings = "hello"    //> greetings : java.lang.String = hello 
Greetings.say("loic")       //> res0: String = hello loic 
Greetings.say("loic")("hi")      //> res1: String = hi loic 

मेरी समस्या यह है कि यह केवल तभी काम करता है जब मैं अपनी ग्रीटिंग्स ऑब्जेक्ट के बाहर निहित वैल्यू को परिभाषित करता हूं। मैं अपने एपीआई (जैसे स्कैला संग्रह एपीआई) का उपयोग आसान बनाने के लिए, मेरी कक्षा के अंदर एक डिफ़ॉल्ट मूल्य के साथ, अंतर्निहित पैरामीटर के साथ विधियां प्रदान करने में सक्षम होना चाहता हूं।

तो मैं यह करने के लिए करना चाहते हैं, लेकिन यह काम नहीं कर रहा (अंतर्निहित मूल्य नहीं मिला):

object Greetings { 
    implicit val greetings = "hello"  
    def say(name: String)(implicit greetings: String): String = greetings + " " +name 
} 

और फिर

Greetings.say("loic")       
Greetings.say("loic")("hi") 

मैं जानता हूँ कि मैं (implicit greetings: String = "hello") के साथ एक डिफ़ॉल्ट मान परिभाषित कर सकते हैं लेकिन अगर मैं कई विधियों को दोहराने से बचने के लिए कक्षा स्तर पर ऐसा करना चाहता हूं।

मुझे लगता है कि मुझे कुछ याद आ रही है क्योंकि मैंने देखा कि CanBuildFromList कक्षा के अंदर परिभाषित किया गया है, उदाहरण के लिए।

class Greetings(implicit val greetings: String = "hello") { 
    def say(name: String): String = greetings + " " + name 
} 

इस तरह मैं उनका डिफ़ॉल्ट मान और इसे ओवरराइड करता है, तो मैं चाहता हूँ कर सकते हैं::

उत्तर

6

मैं एक वैकल्पिक हल मिल गया है

new Greetings().say("loic")      //> res0: String = hello loic 

implicit val greetings = "hi"     //> greetings : java.lang.String = hi 
new Greetings().say("loic")      //> res1: String = hi loic 

new Greetings()("coucou").say("loic")   //> res2: String = coucou loic 

नोट: new Greetings()("coucou") काम कर रहा है, नहीं new Greetings("coucou"), क्योंकि एक वाक्यविन्यास अजीबता के बारे में here समझाया।

+0

यह अजीब नहीं है:

ठीक है, पर्याप्त शब्दाडंबर है, तो यहां आप यह कर सकते है। आम तौर पर आपकी कक्षा 'कक्षा ग्रीटिंग्स() (अंतर्निहित वैल ...)' – thatsIch

24

इस तरह के सामान्य प्रकार का उपयोग String के रूप में एक निहित में करना एक बुरा विचार है। मुख्य कारण यह है कि निहित लुकअप पूरी तरह से प्रकार पर आधारित है, तो क्या होगा यदि कोई और स्ट्रिंग प्रकार के किसी अन्य अंतर्निहित मूल्य को परिभाषित करता है? आप एक संघर्ष के साथ खत्म हो सकता है। तो आपको अपने स्वयं के उद्देश्य के लिए अपना विशिष्ट प्रकार परिभाषित करना चाहिए (स्ट्रिंग के चारों ओर एक साधारण रैपर)।

एक अन्य कारण यह है कि जब अंतर्निहित मूल्यों की तलाश होती है, तो संकलक अंतर्निहित मूल्य प्रकार के साथी ऑब्जेक्ट (यदि कोई हो) में (अन्य स्थानों के बीच) देखेंगे। आप आसानी से देख सकते हैं कि यह कितना उपयोगी है, क्योंकि साथी ऑब्जेक्ट एक डिफ़ॉल्ट अंतर्निहित मूल्य (आपके मामले में) डालने का प्राकृतिक स्थान है। लेकिन यदि निहित मूल्य उस प्रकार का है जो आपके पास नहीं है (जैसे String) तो आप इसके लिए एक साथी ऑब्जेक्ट नहीं लिख सकते हैं, जबकि अपने स्वयं के रैपर प्रकार के साथ कोई समस्या नहीं है। अंतर्निहित केवल सामान्य मानकों से पीछे नहीं डाला जाएगा के बाद से,

case class Greetings(value: String) { 
    override def toString = value 
} 
object Greetings { 
    // this implicit is just so that we don't have to manually wrap 
    // the string when explicitly passing a Greetings instance 
    implicit def stringToGreetings(value: String) = Greetings(value) 

    // default implicit Greetings value 
    implicit val greetings: Greetings ="hello" 

    def say(name: String)(implicit greetings: Greetings): String = greetings + " " +name 
} 
Greetings.say("loic")       
Greetings.say("loic")("hi") 
+0

ठीक है, मुझे लगता है, बहुत धन्यवाद :) – Loic

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