जवाबों:
मैंने सोचा कि यह पहले से ही पूछा गया था, लेकिन, यदि हां, तो सवाल "संबंधित" बार में स्पष्ट नहीं है। तो, यहाँ यह है:
एक दृश्य सीमा कुछ प्रकार के उपयोग को सक्षम करने के लिए स्काला में पेश किया गया एक तंत्र था A
जैसे कि वह कुछ प्रकार का हो B
। विशिष्ट वाक्य रचना यह है:
def f[A <% B](a: A) = a.bMethod
दूसरे शब्दों में, उपलब्ध A
होने के लिए एक अंतर्निहित रूपांतरण होना चाहिए B
, ताकि किसी B
प्रकार की वस्तु पर तरीकों को कॉल किया जा सके A
। मानक पुस्तकालय में दृश्य सीमा का सबसे आम उपयोग (स्काला 2.8.0 से पहले, वैसे भी), Ordered
इस तरह से है:
def f[A <% Ordered[A]](a: A, b: A) = if (a < b) a else b
एक में बदल सकते हैं क्योंकि A
एक में Ordered[A]
, और क्योंकि Ordered[A]
परिभाषित विधि <(other: A): Boolean
, मैं अभिव्यक्ति का उपयोग कर सकते हैं a < b
।
कृपया ध्यान रखें कि दृश्य सीमाएं पदावनत हैं , आपको उनसे बचना चाहिए।
संदर्भ सीमा को स्काला 2.8.0 में पेश किया गया था, और आमतौर पर तथाकथित प्रकार वर्ग पैटर्न के साथ उपयोग किया जाता है , कोड का एक पैटर्न जो हास्केल प्रकार वर्गों द्वारा प्रदान की गई कार्यक्षमता का अनुकरण करता है, हालांकि अधिक क्रियात्मक तरीके से।
जबकि एक बाउंड बाउंड का उपयोग सरल प्रकार (उदाहरण के लिए A <% String
) के साथ किया जा सकता है , एक संदर्भ बाउंड को एक पैरामीटर प्रकार की आवश्यकता होती है , जैसे कि Ordered[A]
ऊपर, लेकिन इसके विपरीत String
।
एक संदर्भ बाउंड दृश्य के अंतर्निहित रूपांतरण को देखने के बजाय एक अंतर्निहित मान का वर्णन करता है । इसका उपयोग यह घोषित करने के लिए किया जाता है कि कुछ प्रकार के लिए , प्रकार का निहित मूल्य उपलब्ध है। वाक्य रचना इस प्रकार है:A
B[A]
def f[A : B](a: A) = g(a) // where g requires an implicit value of type B[A]
यह बाउंड व्यू की तुलना में अधिक भ्रामक है क्योंकि यह तुरंत स्पष्ट नहीं है कि इसका उपयोग कैसे किया जाए। स्काला में उपयोग का सामान्य उदाहरण यह है:
def f[A : ClassManifest](n: Int) = new Array[A](n)
एक Array
पैरामीटर प्रकार पर एक आरंभीकरण के ClassManifest
लिए उपलब्ध होने की आवश्यकता होती है , प्रकार के क्षरण से संबंधित आर्कन कारणों और सरणियों के गैर-मिटाने की प्रकृति के लिए।
पुस्तकालय में एक और बहुत आम उदाहरण थोड़ा और अधिक जटिल है:
def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)
यहां, implicitly
हम चाहते हैं कि किसी भी प्रकार का Ordering[A]
कौन सा वर्ग परिभाषित करता है , हम चाहते हैं कि निहित मूल्य को पुनः प्राप्त करने के लिए उपयोग किया जाता है compare(a: A, b: A): Int
।
हम नीचे ऐसा करने का एक और तरीका देखेंगे।
यह आश्चर्य की बात नहीं होनी चाहिए कि दोनों दृश्य सीमाएँ और संदर्भ सीमाएँ अंतर्निहित मापदंडों के साथ कार्यान्वित की जाती हैं, उनकी परिभाषा दी गई है। वास्तव में, मैंने जो वाक्य-विन्यास दिखाया है, वह वास्तव में क्या होता है, इसके लिए वाक्यविन्यास शर्करा है। नीचे देखें कि वे किस तरह से चीनी:
def f[A <% B](a: A) = a.bMethod
def f[A](a: A)(implicit ev: A => B) = a.bMethod
def g[A : B](a: A) = h(a)
def g[A](a: A)(implicit ev: B[A]) = h(a)
इसलिए, स्वाभाविक रूप से, कोई भी उन्हें अपने पूर्ण वाक्य-विन्यास में लिख सकता है, जो विशेष रूप से संदर्भ सीमा के लिए उपयोगी है:
def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)
देखें सीमा का उपयोग ज्यादातर मेरे पुस्तकालय पैटर्न का लाभ उठाने के लिए किया जाता है , जिसके माध्यम से एक मौजूदा वर्ग में एक "जोड़" तरीके हैं, उन स्थितियों में जहां आप मूल प्रकार को किसी तरह वापस करना चाहते हैं। यदि आपको किसी भी तरह से उस प्रकार को वापस करने की आवश्यकता नहीं है, तो आपको बाध्य दृश्य की आवश्यकता नहीं है।
बाउंड बाउंड उपयोग का क्लासिक उदाहरण हैंडलिंग है Ordered
। ध्यान दें कि Int
नहीं है Ordered
, उदाहरण के लिए, हालांकि एक अंतर्निहित रूपांतरण है। पहले दिए गए उदाहरण को देखने के लिए बाध्य होना चाहिए क्योंकि यह गैर-परिवर्तित प्रकार लौटाता है:
def f[A <% Ordered[A]](a: A, b: A): A = if (a < b) a else b
यह उदाहरण बिना सीमा के काम नहीं करेगा। हालाँकि, अगर मुझे दूसरे प्रकार की वापसी करनी थी, तो मुझे अब बाध्य होने वाले दृश्य की आवश्यकता नहीं है:
def f[A](a: Ordered[A], b: A): Boolean = a < b
मेरे द्वारा पैरामीटर पास करने से पहले यहां रूपांतरण (यदि आवश्यक हो) होता है f
, तो f
इसके बारे में जानने की आवश्यकता नहीं है।
इसके अलावा Ordered
, पुस्तकालय से सबसे आम उपयोग संभाल रहा है String
और Array
, जो जावा कक्षाएं हैं, जैसे वे स्काला संग्रह थे। उदाहरण के लिए:
def f[CC <% Traversable[_]](a: CC, b: CC): CC = if (a.size < b.size) a else b
यदि किसी ने इसे बिना सीमा के देखने की कोशिश की, तो वापसी का प्रकार String
एक WrappedString
(स्कैला 2.8) होगा, और इसी तरह के लिए Array
।
एक ही बात तब भी होती है जब प्रकार केवल रिटर्न प्रकार के पैरामीटर के रूप में उपयोग किया जाता है:
def f[A <% Ordered[A]](xs: A*): Seq[A] = xs.toSeq.sorted
हास्केल के प्रकार वर्गों के संदर्भ के रूप में, मुख्य रूप से टाइपटेक्लेस पैटर्न के रूप में जाना जाने वाला संदर्भ सीमा का उपयोग किया जाता है । मूल रूप से, यह पैटर्न निहित एडाप्टर पैटर्न के एक प्रकार के माध्यम से कार्यक्षमता उपलब्ध करके विरासत का एक विकल्प लागू करता है।
क्लासिक उदाहरण स्काला 2.8 है Ordering
, जो Ordered
स्काला के पुस्तकालय में बदल गया । उपयोग है:
def f[A : Ordering](a: A, b: A) = if (implicitly[Ordering[A]].lt(a, b)) a else b
हालांकि आप आमतौर पर इस तरह लिखा है कि देखेंगे:
def f[A](a: A, b: A)(implicit ord: Ordering[A]) = {
import ord.mkOrderingOps
if (a < b) a else b
}
जो अंदर के कुछ निहितार्थों का लाभ उठाते हैं Ordering
जो पारंपरिक ऑपरेटर शैली को सक्षम करते हैं। स्काला 2.8 में एक और उदाहरण हैNumeric
:
def f[A : Numeric](a: A, b: A) = implicitly[Numeric[A]].plus(a, b)
एक अधिक जटिल उदाहरण नए संग्रह का उपयोग है CanBuildFrom
, लेकिन इसके बारे में पहले से ही बहुत लंबा जवाब है, इसलिए मैं इसे यहां से बचाऊंगा। और, जैसा कि पहले उल्लेख किया गया है, इसका ClassManifest
उपयोग है, जिसे ठोस प्रकारों के बिना नए सरणियों को आरंभ करने के लिए आवश्यक है।
टाइपकास्ट पैटर्न के साथ बंधे संदर्भ का उपयोग आपकी अपनी कक्षाओं द्वारा किए जाने की अधिक संभावना है, क्योंकि वे चिंताओं को अलग करने में सक्षम होते हैं, जबकि दृश्य सीमा को आपके स्वयं के कोड में अच्छे डिजाइन से बचा जा सकता है (इसका उपयोग ज्यादातर किसी और के डिजाइन के आसपास होने के लिए किया जाता है। )।
हालांकि यह लंबे समय से संभव है, संदर्भ सीमा का उपयोग वास्तव में 2010 में दूर हो गया है, और अब यह स्काला के सबसे महत्वपूर्ण पुस्तकालयों और चौखटे में कुछ हद तक पाया जाता है। हालांकि, इसके उपयोग का सबसे चरम उदाहरण, स्कैलाज़ पुस्तकालय है, जो हास्केल की शक्ति को स्काला में लाता है। मैं टाइपकास्टल पैटर्न पर पढ़ने की सलाह देता हूं ताकि उन सभी तरीकों से परिचित हो सकें जिनमें इसका उपयोग किया जा सकता है।
संपादित करें
संबंधित प्रश्न: