दिलचस्प पोस्ट
अपने एंड्रॉइड ऐप में एक पुश अधिसूचना कैसे जोड़ें PHP के साथ एक सीएसएस फ़ाइल पार्स करें उद्देश्य-सी के NSDictionary के जावा बराबर क्या है? Google प्रोटोकॉल बफ़र्स – जावास्क्रिप्ट जावास्क्रिप्ट में <script type = "text / plain" src = …> के माध्यम से प्राप्त सादे पाठ सामग्री को कैसे पहुंचाएं? केस असंवेदनशील std :: string.find () JFrame आइकन कैसे परिवर्तित करें जब ब्राउज़र विंडो / टैब बंद हो जाता है तो एक स्थानीय स्टॉरेज आइटम को कैसे हटाएं? कार्य बार में ब्राउज़र विंडो ब्लिंक बनाएं Codeigniter बैच डालें सरणी कैसे बनाएँ कस्टम अराएडैप्टर में कस्टम GetFilter एंड्रॉइड वस्तु उन्मुख भूमि से सी के साथ संघर्ष? क्लिक करें () इवेंट jquery में दो बार फोन कर रहा है निर्भरता इंजेक्शन कंटेनर के लाभ क्या हैं? बूटस्ट्रैप 3 को ग्लाइफिकॉन को ठीक से प्रदर्शित करने में असमर्थ

Scala में अंतर्निहित समझ

मैं स्काला प्लेफ्रेमवर्क ट्यूटोरियल के माध्यम से अपना रास्ता बना रहा था और मुझे इस स्निपेट कोड पर पहुंचा, जिसने मुझे निराश किया था:

def newTask = Action { implicit request => taskForm.bindFromRequest.fold( errors => BadRequest(views.html.index(Task.all(), errors)), label => { Task.create(label) Redirect(routes.Application.tasks()) } ) } 

इसलिए मैंने जांच करने का निर्णय लिया और इस पोस्ट में आया।

मैं अभी भी इसे नहीं मिलता

इस बीच अंतर क्या है:

 implicit def double2Int(d : Double) : Int = d.toInt 

तथा

 def double2IntNonImplicit(d : Double) : Int = d.toInt 

स्पष्ट तथ्य के अलावा, उनके पास अलग-अलग विधि नाम हैं

मुझे कब implicit उपयोग करना चाहिए और क्यों?

Solutions Collecting From Web of "Scala में अंतर्निहित समझ"

मैं नीचे implicits के मुख्य उपयोग के मामलों की व्याख्या करेंगे, लेकिन अधिक विस्तार के लिए Scala में प्रोग्रामिंग के प्रासंगिक अध्याय देखें

मानदंडों का आकलन करें

एक विधि पर अंतिम पैरामीटर सूची को implicit किया जा सकता है, जिसका मतलब है कि मान उन संदर्भों से लिया जाएगा जिसमें उन्हें कहा जाता है। यदि दायरे प्रकार के दायरे में कोई निहित मूल्य नहीं है, तो यह संकलन नहीं करेगा। चूंकि अंतर्निहित मान को एक मूल्य से हल करना चाहिए और संघर्ष से बचने के लिए, यह अपने उद्देश्य के लिए विशिष्ट प्रकार बनाने के लिए एक अच्छा विचार है, जैसे किसी अंतर्निहित Int को खोजने के लिए आपके तरीकों की आवश्यकता नहीं है!

उदाहरण:

  // probably in a library class Prefixer(val prefix: String) def addPrefix(s: String)(implicit p: Prefixer) = p.prefix + s // then probably in your application implicit val myImplicitPrefixer = new Prefixer("***") addPrefix("abc") // returns "***abc" 

अप्रत्यक्ष रूपांतरण

जब कंपाइलर संदर्भ के लिए गलत प्रकार की अभिव्यक्ति पाता है, तो वह उस प्रकार के एक अंतर्निहित Function मूल्य की खोज करेगा जो उसे टाइप-चेक करने की अनुमति देगा। इसलिए यदि A की आवश्यकता होती है और इसे B , तो यह दायरे में टाइप B => A निहित मूल्य की खोज करेगा (यह B और A साथी ऑब्जेक्ट्स जैसे कुछ अन्य स्थानों की जांच करता है, यदि वे मौजूद हैं)। चूंकि def ऑब्जेक्ट Function ऑब्जेक्ट्स में "eta-expanded" हो सकता है, एक implicit def xyz(arg: B): A भी वैसे भी करेगा।

तो आपके तरीकों के बीच का अंतर यह है कि जब एक Double पाया जाता है, लेकिन एक Int की आवश्यकता होती है तो कंपाइलर द्वारा आपके लिए implicit चिह्नित चिह्नित किया जाएगा।

 implicit def doubleToInt(d: Double) = d.toInt val x: Int = 42.0 

उसी के रूप में काम करेगा

 def doubleToInt(d: Double) = d.toInt val x: Int = doubleToInt(42.0) 

दूसरे में हमने मैन्युअल रूपांतरण डाला है; पहले में कंपाइलर ने स्वयं को समान किया। बाएं हाथ की तरफ टाइप एनोटेशन की वजह से रूपांतरण की आवश्यकता है


Play से आपकी पहली स्निपेट के बारे में:

Play दस्तावेजों से इस पृष्ठ पर क्रियाओं को समझाया गया है ( एपीआई दस्तावेज़ भी देखें)। आप उपयोग कर रहे हैं

 apply(block: (Request[AnyContent]) ⇒ Result): Action[AnyContent] 

Action ऑब्जेक्ट पर (जो कि एक ही नाम की विशेषता के साथ साथी है)

इसलिए हमें तर्क के रूप में एक समारोह प्रदान करने की आवश्यकता है, जिसे रूप में एक शाब्दिक रूप में लिखा जा सकता है

 request => ... 

एक समारोह में शाब्दिक, => एक मूल्य घोषणा से पहले का हिस्सा है, और यदि आप चाहें तो implicit चिह्नित किया जा सकता है, बस किसी अन्य val घोषणा की तरह। यहां, इस प्रकार की जांच करने के लिए request को चिह्नित करने की आवश्यकता नहीं है, लेकिन ऐसा करने से यह किसी भी तरीके के लिए एक निहित मूल्य के रूप में उपलब्ध होगा जो फ़ंक्शन के भीतर इसकी आवश्यकता हो सकती है (और जाहिर है, इसे स्पष्ट रूप से उपयोग किया जा सकता है कुंआ)। इस विशेष मामले में, ऐसा इसलिए किया गया है क्योंकि फॉर्म क्लास के bindFromRequest विधि को एक अन्तर्निहित Request तर्क की आवश्यकता है।

चेतावनी: विवेकपूर्ण तरीके से व्यंग्य शामिल हैं! YMMV …

लुइगी का उत्तर पूर्ण और सही है यह केवल इसे उदाहरण के साथ थोड़ा विस्तारित करने के लिए है कि आप प्रवीणता का उपयोग कैसे कर सकते हैं, जैसा कि स्काला परियोजनाओं में अक्सर होता है वास्तव में अक्सर, आप संभवत: इसे "बेस्ट प्रैक्टिस" गाइडों में से एक में भी ढूंढ सकते हैं।

 object HelloWorld { case class Text(content: String) case class Prefix(text: String) implicit def String2Text(content: String)(implicit prefix: Prefix) = { Text(prefix.text + " " + content) } def printText(text: Text): Unit = { println(text.content) } def main(args: Array[String]): Unit = { printText("World!") } // Best to hide this line somewhere below a pile of completely unrelated code. // Better yet, import its package from another distant place. implicit val prefixLOL = Prefix("Hello") } 

क्यों और जब आप request पैरामीटर को implicit रूप में चिह्नित करना चाहिए:

कुछ विधियां जो आप अपनी कार्रवाई के शरीर में उपयोग करेंगे, जैसे एक निहित पैरामीटर सूची है, उदाहरण के लिए, Form.scala एक विधि को परिभाषित करती है:

 def bindFromRequest()(implicit request: play.api.mvc.Request[_]): Form[T] = { ... } 

आपको यह जरूरी नहीं पता है कि आप केवल myForm.bindFromRequest() कॉल कर myForm.bindFromRequest() आपको स्पष्ट रूप से अंतर्निहित तर्क प्रदान करने की ज़रूरत नहीं है। नहीं, आप किसी भी वैध उम्मीदवार वस्तु को देखने के लिए कम्पाइलर को छोड़ दें , जब वह किसी विधि कॉल के दौरान हर बार पास हो जाता है जिसके लिए अनुरोध की एक आवृत्ति की आवश्यकता होती है। चूंकि आपके पास एक अनुरोध उपलब्ध है, इसलिए आपको केवल उसे implicit रूप में चिह्नित करने की आवश्यकता है।

आप इसे निहित उपयोग के लिए स्पष्ट रूप से चिह्नित करते हैं।

आप कंपाइलर को संकेत देते हैं कि प्ले फ्रेमवर्क द्वारा भेजे गए अनुरोध ऑब्जेक्ट का उपयोग करने के लिए "ठीक" है (हम नाम "अनुरोध" देते हैं, लेकिन आवश्यकता होती है, जहां कहीं भी "r" या "req" का इस्तेमाल किया हो सकता है) "स्ले पर" ।

 myForm.bindFromRequest() 

इसे देखें? यह वहाँ नहीं है, लेकिन यह वहाँ है!

यह आपकी आवश्यकता के मुताबिक हर जगह मैन्युअल रूप से इसे स्लॉट करने के बिना ही होता है (लेकिन यदि आप चाहें तो इसे स्पष्ट रूप से पारित कर सकते हैं, कोई फर्क नहीं पड़ता अगर यह implicit या नहीं):

 myForm.bindFromRequest()(request) 

इसे निहित के रूप में चिह्नित किए बिना, आपको उपरोक्त करना होगा इसे निहित के रूप में चिह्नित करने की आवश्यकता नहीं है।

आपको implicit रूप में अनुरोध को कब चिह्नित करना चाहिए? आप केवल वास्तविकता की आवश्यकता है अगर आप उन विधियों का उपयोग कर रहे हैं जो अनुरोध की एक आवृत्ति की उम्मीद की एक अन्तर्निहित पैरामीटर सूची की घोषणा करते हैं। लेकिन इसे सरल रखने के लिए, आप हमेशा अनुरोध implicit हमेशा चिह्नित करने की आदत में आ सकते हैं इस तरह से आप बस खूबसूरत श्लोक कोड लिख सकते हैं।

इसके अलावा, उपरोक्त मामले में only one निहित समारोह होना चाहिए जिसका प्रकार double => Int अन्यथा, कंपाइलर भ्रमित हो जाता है और ठीक से संकलन नहीं करेगा।

 //this won't compile implicit def doubleToInt(d: Double) = d.toInt implicit def doubleToIntSecond(d: Double) = d.toInt val x: Int = 42.0