स्काला संदर्भ और दृश्य सीमा क्या हैं?


267

एक सरल तरीके से, संदर्भ और दृश्य सीमाएं क्या हैं और उनके बीच क्या अंतर है?

कुछ आसान से उदाहरण भी महान होंगे!

जवाबों:


477

मैंने सोचा कि यह पहले से ही पूछा गया था, लेकिन, यदि हां, तो सवाल "संबंधित" बार में स्पष्ट नहीं है। तो, यहाँ यह है:

एक बाउंड क्या है?

एक दृश्य सीमा कुछ प्रकार के उपयोग को सक्षम करने के लिए स्काला में पेश किया गया एक तंत्र था 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

एक संदर्भ बाउंड दृश्य के अंतर्निहित रूपांतरण को देखने के बजाय एक अंतर्निहित मान का वर्णन करता है । इसका उपयोग यह घोषित करने के लिए किया जाता है कि कुछ प्रकार के लिए , प्रकार का निहित मूल्य उपलब्ध है। वाक्य रचना इस प्रकार है:AB[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 में दूर हो गया है, और अब यह स्काला के सबसे महत्वपूर्ण पुस्तकालयों और चौखटे में कुछ हद तक पाया जाता है। हालांकि, इसके उपयोग का सबसे चरम उदाहरण, स्कैलाज़ पुस्तकालय है, जो हास्केल की शक्ति को स्काला में लाता है। मैं टाइपकास्टल पैटर्न पर पढ़ने की सलाह देता हूं ताकि उन सभी तरीकों से परिचित हो सकें जिनमें इसका उपयोग किया जा सकता है।

संपादित करें

संबंधित प्रश्न:


9
आपका बहुत बहुत धन्यवाद। मुझे पता है कि यह पहले भी उत्तर दिया जा चुका है, और हो सकता है कि मैंने तब ध्यान से नहीं पढ़ा हो, लेकिन यहाँ आपका स्पष्टीकरण सबसे स्पष्ट है जो मैंने देखा है। तो, फिर से धन्यवाद।
चेरन

3
@chrsan मैंने दो और सेक्शन जोड़े हैं, जहाँ प्रत्येक एक का उपयोग करने पर अधिक विस्तार से जाना जाता है।
डैनियल सी। सोबरल

2
मुझे लगता है कि यह एक उत्कृष्ट व्याख्या है। अगर यह आपके साथ ठीक है तो मैं अपने जर्मन ब्लॉग (dgronau.wordpress.com) के लिए इसका अनुवाद करना चाहता हूँ।
लांडेई

3
यह इस विषय का अब तक का सबसे अच्छा और सबसे व्यापक विवरण है जो मैंने अब तक पाया है। आपका बहुत - बहुत धन्यवाद!
fotNelton

2
Sooo, आपकी स्काला किताब कब आ रही है, और मैं इसे कहाँ खरीद सकता हूँ :)
wfbarksdale
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.