यहाँ कुछ सरल तरीके का उपयोग करने के कुछ कारण दिए गए हैं implicitly
।
समझने के लिए / Implicit Views का निवारण करें
जब चयन का उपसर्ग (उदाहरण के लिए विचार करें, the.prefix.selection(args)
इसमें एक सदस्य शामिल नहीं होता है , तब भी selection
लागू किया जा args
सकता है args
) वर्तमान या संलग्न स्कोप्स में, विरासत में मिला, या आयात किया गया, जो कि या तो उस प्रकार के कार्य हैं जो परिभाषित, या समकक्ष निहित विधियों के the.prefix
साथ एक प्रकार के हैं selection
।
scala> 1.min(2) // Int doesn't have min defined, where did that come from?
res21: Int = 1
scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>
scala> res22(1) //
res23: AnyRef{def min(i: Int): Int} = 1
scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt
जब कोई अभिव्यक्ति एक्सपेक्टेड टाइप के अनुरूप न हो तो इम्प्लिमेंट व्यू को भी ट्रिगर किया जा सकता है:
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
यहाँ संकलक इस समारोह के लिए लग रहा है:
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
एक प्रसंग सीमा द्वारा प्रस्तुत इंप्लिमेंट पैरामीटर तक पहुँचना
Implicit Views की तुलना में Implicit पैरामीटर स्कैला की एक अधिक महत्वपूर्ण विशेषता है। वे टाइप क्लास पैटर्न का समर्थन करते हैं। मानक पुस्तकालय कुछ स्थानों पर इसका उपयोग करता है - देखें scala.Ordering
और इसका उपयोग कैसे किया जाता है SeqLike#sorted
। Array मेनिफ़ेस्ट और CanBuildFrom
उदाहरणों को पास करने के लिए Implicit Parameters का भी उपयोग किया जाता है ।
स्कैला 2.8, निहित मापदंडों के लिए एक शॉर्टहैंड सिंटैक्स की अनुमति देता है, जिसे संदर्भ सीमा कहा जाता है। संक्षेप में, एक प्रकार के पैरामीटर के साथ एक विधि जिसके A
लिए एक अंतर्निहित पैरामीटर की आवश्यकता होती है M[A]
:
def foo[A](implicit ma: M[A])
के रूप में फिर से लिखा जा सकता है:
def foo[A: M]
लेकिन निहित पैरामीटर पारित करने का क्या मतलब है, लेकिन इसका नामकरण नहीं है? विधि को लागू करते समय यह कैसे उपयोगी हो सकता है foo
?
अक्सर, निहित पैरामीटर को सीधे संदर्भित करने की आवश्यकता नहीं होती है, इसे अंतर्निहित तर्क के रूप में एक अन्य विधि जिसे कहा जाता है, के माध्यम से सुरंगित किया जाएगा। यदि यह आवश्यक है, तो आप अभी भी संदर्भ बाउंड के साथ terse विधि हस्ताक्षर को बनाए रख सकते हैं, और implicitly
मूल्य को भौतिक बनाने के लिए कॉल कर सकते हैं:
def foo[A: M] = {
val ma = implicitly[M[A]]
}
स्पष्ट रूप से निहित मापदंडों का एक सबसेट पास करना
मान लीजिए कि आप एक ऐसी विधि कह रहे हैं जो एक व्यक्ति को टाइप क्लास आधारित दृष्टिकोण का उपयोग करके प्रिंट करता है:
trait Show[T] { def show(t: T): String }
object Show {
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}
case class Person(name: String, age: Int)
object Person {
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
}
}
val p = Person("bob", 25)
implicitly[Show[Person]].show(p)
क्या होगा अगर हम उस तरीके को बदलना चाहते हैं जो नाम आउटपुट है? हम स्पष्ट रूप से कॉल कर सकते हैं PersonShow
, स्पष्ट रूप से एक विकल्प पास कर सकते हैं Show[String]
, लेकिन हम चाहते हैं कि कंपाइलर पास हो Show[Int]
।
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)