2010-09-08 22 views
11

में कॉन्वर्सिस नोटेशन या जेनेरिक सीमाओं का उपयोग करते समय स्कैला भिन्नता को सामान्य प्रकार के तर्क पर + और - जैसे भिन्न ऑपरेटरों के साथ परिभाषित किया जा सकता है। उदाहरण के लिए List प्रकार मानक पुस्तकालय में covariant है।स्कैला

class List[+A] 

तो एक covariant सूची के साथ एक समारोह इस तरह परिभाषित किया जा सकता:

def foo[A](list : List[A]) 

भी विचरण सामान्य सीमा के साथ नकल करते जा सकता है। तो हम भी, इस

def foo[A](list : List[_:< A]) 

निश्चित रूप से यह कोई मतलब नहीं है लिख सकते हैं क्योंकि list पहले से ही covariant है। लेकिन वही चाल उन प्रकारों के लिए की जा सकती है जो कॉन्वेंट नहीं हैं। (जैसे Stack)। बेशक, स्टैक (एकत्रीकरण की विरासत) से भी एक नए प्रकार का निर्माण किया जा सकता है जो कि कॉन्वर्सेंट है।

तो मेरे सवालों का:

  1. जब विचरण के लिए सामान्य सीमा का उपयोग किया जाना चाहिए? और हमें एक नया कॉन्वेंट प्रकार कब बनाना चाहिए?
  2. सामान्य सीमाएं केवल भिन्नता के लिए उपयोगी हैं, या वे अधिक (भाषा अवधारणाओं) घोषित कर सकते हैं।
  3. यदि वे केवल भिन्नता के लिए उपयोगी हैं, तो केवल जावा के साथ संगतता के लिए सीमाएं हैं?

अग्रिम :)

+1

मैं इस सवाल को दोगुना करता हूं - भिन्नता स्कैला का सबसे कठिन हिस्सा है और मैं वास्तव में इसे अच्छी तरह समझ नहीं पा रहा हूं। "Blah-blah covariant blah contravariant स्थिति blah-blah में दिखाई दिया": पी – Jeriho

+2

जब मैंने कुछ फ़ंक्शन गुणों (फ़ंक्शन 1, फ़ंक्शन 2, आदि) की परिभाषाओं को देखा तो मुझे भिन्नता दिखाई दी। फ़ंक्शन विशेषता आउटपुट प्रकार पर सभी कॉन्वर्सेंट हैं और इनपुट (पैरामीटर) प्रकारों पर contravariant। उदाहरण के लिए, 'Any => यूनिट' प्रकार का एक फ़ंक्शन तब भी उपयोग किया जा सकता है जहां 'स्ट्रिंग => यूनिट' प्रकार के फ़ंक्शन की अपेक्षा की जाती है, क्योंकि 'Any => Unit' फ़ंक्शन स्ट्रिंग को इसके इनपुट के रूप में ले सकता है (क्योंकि यह कर सकता है इसके इनपुट के रूप में कुछ भी ले लो।) यही कारण है कि विधि पैरामीटर के प्रकार एक "contravariant स्थिति" हैं। –

उत्तर

13

यदि कोई प्रकार स्वाभाविक रूप से संवैधानिक या contravariant है तो आपको इसे घोषित करना चाहिए। आपके उपयोगकर्ता इसके लिए आपको धन्यवाद देंगे। जावा की वजह से उपयोग साइट भिन्नता वास्तव में अधिकतर है। दरअसल, इस तरह के Array[T <: Number] के रूप में एक प्रकार एक अस्तित्व प्रकार के लिए एक आशुलिपि के रूप में व्यवहार किया जाता है:

ArrayBuffer[T] forSome { type T <: Number } 

अस्तित्व प्रकार स्काला में एक सुंदर भारी वाक्य रचना की है। यह जानबूझकर है, क्योंकि हम आपको सलाह देते हैं कि आप उनका अधिक उपयोग न करें। आपको अस्तित्व के प्रकार की आवश्यकता कब होगी?

  1. List<? extends Number> जैसे वाइल्डकार्ड के साथ जावा प्रकार के एनालॉग लिखने के लिए।
  2. जावा कच्चे प्रकार के एनालॉग लिखने के लिए, जैसे कि List

जावा में, कच्चे प्रकार और वाइल्डकार्ड प्रकार काफी ही नहीं हैं और न ही एक अस्तित्व प्रकार के रूप में (भले ही हम जानते हैं कि वे क्या नहीं कर रहे हैं, यह ठीक राज्य के लिए वे क्या कर रहे हैं बहुत मुश्किल है) काफी एक ही है।लेकिन वे प्रैक्टिस में अस्तित्व के लिए काफी करीब हैं, ताकि स्कैला उन्हें इस प्रकार के प्रकार से मैप करने से दूर हो जाए।

6
  1. जब एक नया सामान्य प्रकार बनाने, का कहना है कि फू [टी], आप यह निर्धारित करने के उस प्रकार, covariant contravariant या अपरिवर्तनीय है और यह घोषणा फू [कठिन प्रयास करना चाहिए में THX + टी], फू [-टी] या फू [टी] क्रमशः। माना जाता है कि यह थोड़ा मुश्किल हो सकता है। हालांकि, यह सामान्य सीमाओं का उपयोग करके फू का उपयोग करने के लिए हर बार उस निर्णय को बनाने के लिए फू के उपयोगकर्ता को मुक्त करता है। संक्षेप में: कॉल साइट भिन्नता पर घोषणा साइट भिन्नता पसंद करते हैं जब भिन्नता प्रकार की संपत्ति होती है।

बीटीडब्ल्यू, मार्टिन ओडर्स्की, लेक्स स्पून और बिल वेनेर्स द्वारा स्कैला पुस्तक में प्रोग्रामिंग में भिन्नता के बारे में कुछ महान समुद्र तट हैं। अध्याय 1 9 पैरामैट्रिजेशन टाइप करें।