स्केल: सार प्रकार बनाम जेनरिक


250

मैं ए टूर ऑफ स्काला: एब्सट्रैक्ट टाइप्स पढ़ रहा था । अमूर्त प्रकारों का उपयोग करना कब बेहतर होता है?

उदाहरण के लिए,

abstract class Buffer {
  type T
  val element: T
}

बल्कि वह जेनेरिक, उदाहरण के लिए,

abstract class Buffer[T] {
  val element: T
}

जवाबों:


257

आपके पास इस मुद्दे पर एक अच्छा दृष्टिकोण है:


मार्टिन ओडस्की, भाग III के साथ स्काला के टाइप सिस्टम ए कन्वर्सेशन का उद्देश्य
विथ बिल वेनर्स एंड फ्रैंक सोमरस (18 मई, 2009)

अपडेट (अक्टूबर २०० ९): बिल वीनर्स के इस नए लेख में वास्तव में नीचे दिए गए उदाहरणों का वर्णन किया गया है: स्केल
प्रकार के सदस्य बनाम जेनेरिक टाइप पैरामीटर बनाम स्काला (अंत में सारांश देखें)


(यहां पहला साक्षात्कार, मई 2009 का प्रासंगिक उद्धरण है, मेरा जोर)

सामान्य सिद्धांत

हमेशा अमूर्तता की दो धारणाएँ रही हैं:

  • पैरामीटरकरण और
  • अमूर्त सदस्य।

जावा में आपके पास भी दोनों हैं, लेकिन यह इस बात पर निर्भर करता है कि आप किस चीज पर अमूर्त हैं।
जावा में आपके पास सार विधियां हैं, लेकिन आप एक विधि को पैरामीटर के रूप में पारित नहीं कर सकते हैं।
आपके पास सार क्षेत्र नहीं हैं, लेकिन आप एक मान को पैरामीटर के रूप में पारित कर सकते हैं।
और इसी तरह आपके पास अमूर्त प्रकार के सदस्य नहीं हैं, लेकिन आप एक पैरामीटर के रूप में एक प्रकार निर्दिष्ट कर सकते हैं।
तो जावा में आपके पास भी ये तीनों हैं, लेकिन इस बात का भेद है कि आप किस अमूर्त सिद्धांत का इस्तेमाल कर सकते हैं। और आप तर्क दे सकते हैं कि यह भेद काफी मनमाना है।

स्केल रास्ता

हमने तीनों प्रकार के सदस्यों के लिए समान निर्माण सिद्धांत तय किए ।
तो आपके पास अमूर्त क्षेत्र और साथ ही मूल्य पैरामीटर हो सकते हैं।
आप मानकों (या "कार्यों") को मापदंडों के रूप में पारित कर सकते हैं, या आप उन पर सार कर सकते हैं।
आप पैरामीटर के रूप में प्रकार निर्दिष्ट कर सकते हैं, या आप उन पर सार कर सकते हैं।
और जो हमें वैचारिक रूप से मिलता है वह यह है कि हम एक दूसरे के संदर्भ में मॉडल बना सकते हैं। कम से कम सिद्धांत रूप में, हम ऑब्जेक्ट-ओरिएंटेड एब्सट्रैक्शन के रूप में हर प्रकार के मापदंडों को व्यक्त कर सकते हैं। तो एक तरह से आप कह सकते हैं कि स्काला एक अधिक रूढ़िवादी और पूर्ण भाषा है।

क्यों?

क्या, विशेष रूप से, अमूर्त प्रकार आप खरीदते हैं इन covariance समस्याओं के लिए एक अच्छा इलाज है जो हमने पहले बात की थी।
एक मानक समस्या, जो लंबे समय से है, जानवरों और खाद्य पदार्थों की समस्या है।
पहेली में Animalएक विधि के साथ एक वर्ग था eat, जो कुछ भोजन खाता है।
समस्या यह है कि यदि हम पशु को उपवर्ग में रखते हैं और गाय जैसे वर्ग रखते हैं, तो वे केवल ग्रास ही खाएंगे और मनमाना भोजन नहीं करेंगे। उदाहरण के लिए, एक गाय मछली नहीं खा सकती थी।
आप जो चाहते हैं वह यह कहने में सक्षम है कि एक गाय के पास एक खाने की विधि है जो केवल घास खाती है न कि अन्य चीजें।
वास्तव में, आप जावा में ऐसा नहीं कर सकते क्योंकि यह पता चला है कि आप बिना किसी अनचाहे स्थितियों का निर्माण कर सकते हैं, जैसे कि एक फलन को एक Apple वैरिएबल को असाइन करने की समस्या के बारे में जो मैंने पहले बात की थी।

इसका उत्तर यह है कि आप पशु वर्ग में एक अमूर्त प्रकार जोड़ते हैं
आप कहते हैं, मेरे नए पशु वर्ग का एक प्रकार है SuitableFood, जिसे मैं नहीं जानता।
तो यह एक अमूर्त प्रकार है। आप प्रकार का कार्यान्वयन नहीं करते हैं। तब आपके पास एक ऐसी eatविधि है जो केवल खाती है SuitableFood
और फिर Cowकक्षा में मैं कहूंगा, ठीक है, मेरे पास एक गाय है, जो कक्षा का विस्तार करती है Animal, और इसके लिए Cow type SuitableFood equals Grass
इसलिए अमूर्त प्रकार एक सुपरक्लास में एक प्रकार की यह धारणा प्रदान करते हैं जो मुझे नहीं पता है, जिसे मैं बाद में उप-वर्ग में कुछ ऐसी चीजों के साथ भर देता हूं जो मुझे पता है

मानकीकरण के साथ भी?

वास्तव में आप कर सकते हैं। आप भोजन के प्रकार के साथ वर्ग पशु को पैरामीटर कर सकते हैं।
लेकिन व्यवहार में, जब आप ऐसा करते हैं, तो कई अलग-अलग चीजों के साथ, यह मापदंडों के विस्फोट की ओर जाता है , और आमतौर पर, मापदंडों की सीमा में और क्या है ।
1998 ECOOP में, किम ब्रूस, फिल वाडलर, और मेरे पास एक पेपर था जहां हमने दिखाया कि जैसे-जैसे आप उन चीजों की संख्या बढ़ाते हैं, जिन्हें आप नहीं जानते हैं, विशिष्ट कार्यक्रम चतुष्कोणीय रूप से बढ़ेगा
इसलिए मापदंडों को नहीं करने के लिए बहुत अच्छे कारण हैं, लेकिन इन सार सदस्यों के पास होने के लिए, क्योंकि वे आपको यह द्विघात झटका नहीं देते हैं।


टिप्पणी में पुछता है:

क्या आपको लगता है कि निम्नलिखित एक उचित सारांश है:

  • अमूर्त प्रकार का उपयोग 'has-a' या 'use-a' रिश्तों में किया जाता है (जैसे a Cow eats Grass)
  • जहाँ सामान्य रूप से 'रिश्ते' (जैसे List of Ints) होते हैं

मुझे यकीन नहीं है कि यह संबंध अमूर्त प्रकार या जेनरिक का उपयोग करने के बीच भिन्न है। क्या अलग है:

  • उनका उपयोग कैसे किया जाता है, और
  • कैसे पैरामीटर सीमा का प्रबंधन कर रहे हैं।

यह समझने के लिए कि मार्टिन क्या बोल रहा है जब "मापदंडों के विस्फोट की बात आती है, और आमतौर पर, मापदंडों की सीमा में अधिक क्या होता है ", और इसके बाद के चतुष्कोणीय विकास जब अमूर्त प्रकार जेनेरिक का उपयोग करके मॉडलिंग की जाती है, तो आप कागज पर विचार कर सकते हैं " स्केलर कंपोनेंट एब्स्ट्रेक्शन। "द्वारा लिखित ... मार्टिन ओडस्की, और ओओपीएसएलए 2005 के लिए मथायस ज़ेंगर, प्रोजेक्ट पालकॉम के प्रकाशनों में संदर्भित (2007 में समाप्त)।

प्रासंगिक अर्क

परिभाषा

अमूर्त प्रकार के सदस्य ठोस प्रकार के घटकों पर अमूर्त करने का एक लचीला तरीका प्रदान करते हैं। एसएमएल हस्ताक्षर
में उनके उपयोग के समान, घटक प्रकार के घटकों के बारे में जानकारी छिपा सकते हैं । ऑब्जेक्ट-ओरिएंटेड फ्रेमवर्क में, जहाँ कक्षाएं वंशानुक्रम द्वारा विस्तारित की जा सकती हैं, उन्हें मानकीकरण के लचीले साधन के रूप में भी इस्तेमाल किया जा सकता है (अक्सर इसे परिवार बहुरूपता कहा जाता है, उदाहरण के लिए इस वेबलॉग प्रविष्टि को देखें , और एरिक अर्न्स्ट द्वारा लिखित पेपर )।

(नोट: पारिवारिक बहुरूपता को वस्तु-उन्मुख भाषाओं के लिए पुन: प्रयोज्य अभी तक प्रकार-सुरक्षित पारस्परिक पुनरावर्ती वर्गों के समर्थन के लिए प्रस्तावित किया गया है।
एक महत्वपूर्ण विचार परिवारों की धारणा है, जो पारस्परिक रूप से पुनरावर्ती वर्गों के लिए उपयोग किए जाते हैं)

बाध्य प्रकार अमूर्त

abstract class MaxCell extends AbsCell {
type T <: Ordered { type O = T }
def setMax(x: T) = if (get < x) set(x)
}

यहां, टी के प्रकार की घोषणा एक ऊपरी प्रकार की बाध्यता से बाध्य है जिसमें एक वर्ग का नाम क्रमबद्ध और एक शोधन शामिल है { type O = T }
ऊपरी बाध्य टी उपविशेषों में उप के आदेशों को उन आदेशों के उपप्रकारों तक सीमित कर देता है, जिनके लिए सदस्य Oके प्रकार equals T
इस अड़चन के कारण, <ऑर्डर किए गए क्लास के तरीके को एक रिसीवर पर लागू होने की गारंटी दी जाती है और टाइप T का एक तर्क दिया जाता है
। उदाहरण से पता चलता है कि बंधे हुए टाइप मेंबर खुद बाउंड के हिस्से के रूप में दिखाई दे सकते हैं।
(यानी स्काला एफ-बाउंड पॉलिमॉर्फिज्म का समर्थन करता है )

(नोट, पीटर कैनिंग, विलियम कुक, वाल्टर हिल, वाल्टर ओलथॉफ पेपर से: बाउंडेड
मात्रा का ठहराव कार्डेली और वेगनर द्वारा टाइपिंग कार्यों के रूप में पेश किया गया था जो किसी दिए गए प्रकार के सभी उपप्रकारों पर समान रूप से काम करते हैं।
उन्होंने एक सरल "ऑब्जेक्ट" मॉडल को परिभाषित किया है । और टाइप-चेक फ़ंक्शंस के लिए बाध्य परिमाणीकरण का उपयोग किया गया है, जो "विशेषता" के एक निर्दिष्ट सेट वाले सभी ऑब्जेक्ट्स पर समझ में आता है।
ऑब्जेक्ट-ओरिएंटेड भाषाओं की अधिक यथार्थवादी प्रस्तुति उन ऑब्जेक्ट्स की अनुमति देगा जो पुनरावर्ती-परिभाषित प्रकारों के तत्व हैं ।
इस संदर्भ में, बाउंडेड। परिमाणीकरण अब अपने इच्छित उद्देश्य को पूरा नहीं करता है। ऐसे कार्यों को खोजना आसान है जो सभी वस्तुओं पर एक निर्दिष्ट पद्धति के साथ समझ में आता है, लेकिन जिसे कार्डेली-वेगनर प्रणाली में टाइप नहीं किया जा सकता है।
ऑब्जेक्ट-ओरिएंटेड भाषाओं में टाइप किए गए बहुरूप कार्यों के लिए एक आधार प्रदान करने के लिए, हम एफ-बाउंड मात्रा का परिचय देते हैं)

एक ही सिक्के के दो चेहरे

प्रोग्रामिंग भाषाओं में अमूर्तता के दो प्रमुख रूप हैं:

  • पैरामीटरकरण और
  • अमूर्त सदस्य।

पहला रूप कार्यात्मक भाषाओं के लिए विशिष्ट है, जबकि दूसरा रूप आमतौर पर ऑब्जेक्ट-ओरिएंटेड भाषाओं में उपयोग किया जाता है।

परंपरागत रूप से, जावा मानों के लिए मानकीकरण का समर्थन करता है, और संचालन के लिए सदस्य अमूर्तता। जेनेरिक के साथ हाल ही में जावा 5.0 प्रकार के लिए भी मानकीकरण का समर्थन करता है।

स्काला में जेनरिक को शामिल करने के तर्क दो-गुना हैं:

  • सबसे पहले, अमूर्त प्रकार में एन्कोडिंग हाथ से करने के लिए सीधा नहीं है। सुगमता में कमी के अलावा, अमूर्त प्रकार के नामों के बीच आकस्मिक नाम संघर्षों की समस्या भी है जो प्रकार के मापदंडों का अनुकरण करते हैं।

  • दूसरा, जेनरिक और अमूर्त प्रकार आमतौर पर स्काला कार्यक्रमों में अलग भूमिका निभाते हैं।

    • आम तौर पर जेनरिक का उपयोग तब किया जाता है जब किसी को सिर्फ इंस्टेंटेशन टाइप करना होता है , जबकि
    • अमूर्त प्रकार आमतौर पर तब उपयोग किए जाते हैं जब ग्राहक कोड से सार प्रकार को संदर्भित करने की आवश्यकता होती है ।
      उत्तरार्द्ध विशेष रूप से दो स्थितियों में उत्पन्न होता है:
    • एक ग्राहक कोड से एक प्रकार के सदस्य की सटीक परिभाषा को छिपाने के लिए, SML- शैली मॉड्यूल सिस्टम से ज्ञात इनकैप्सुलेशन प्राप्त करना चाहता हो सकता है।
    • या कोई व्यक्ति परिवार के बहुरूपता को प्राप्त करने के लिए उपवर्गों में covariantly प्रकार को ओवरराइड करना चाह सकता है।

बंधी हुई बहुरूपता वाली प्रणाली में, जेनेटिक्स में अमूर्त प्रकार को फिर से लिखना एक प्रकार का सीमा विस्तार हो सकता है ।


अद्यतन अक्टूबर 2009

स्केल प्रकार के सदस्य बनाम स्काला में सामान्य प्रकार के पैरामीटर (बिल वेनर)

(जोर मेरा)

सार प्रकार के सदस्यों के बारे में अब तक का मेरा अवलोकन है कि वे मुख्य रूप से सामान्य प्रकार के मापदंडों से बेहतर विकल्प हैं जब:

  • आप लोगों को लक्षणों के माध्यम से उन प्रकारों की परिभाषाओं में मिश्रण करने देना चाहते हैं
  • आपको लगता है कि जब यह परिभाषित किया जा रहा है तो सदस्य के नाम का स्पष्ट उल्लेख कोड पठनीयता में मदद करेगा

उदाहरण:

यदि आप तीन अलग-अलग फ़िक्चर ऑब्जेक्ट को परीक्षणों में पास करना चाहते हैं, तो आप ऐसा कर पाएंगे, लेकिन आपको तीन प्रकार निर्दिष्ट करने होंगे, प्रत्येक पैरामीटर के लिए एक। इस प्रकार मैंने टाइप पैरामीटर दृष्टिकोण अपना लिया था, आपकी सुइट कक्षाएं इस तरह से समाप्त हो सकती थीं:

// Type parameter version
class MySuite extends FixtureSuite3[StringBuilder, ListBuffer, Stack] with MyHandyFixture {
  // ...
}

जबकि प्रकार सदस्य दृष्टिकोण के साथ यह इस प्रकार होगा:

// Type member version
class MySuite extends FixtureSuite3 with MyHandyFixture {
  // ...
}

अमूर्त प्रकार के सदस्यों और सामान्य प्रकार के मापदंडों के बीच एक अन्य मामूली अंतर यह है कि जब एक सामान्य प्रकार का पैरामीटर निर्दिष्ट किया जाता है, तो कोड के पाठकों को टाइप पैरामीटर का नाम नहीं दिखता है। इस प्रकार कोड की इस लाइन को देखने के लिए कोई था:

// Type parameter version
class MySuite extends FixtureSuite[StringBuilder] with StringBuilderFixture {
  // ...
}

उन्हें पता नहीं होगा कि स्ट्रिंगबर्ल के रूप में निर्दिष्ट प्रकार के पैरामीटर का नाम क्या था, इसे देखे बिना। जबकि सार प्रकार सदस्य दृष्टिकोण में कोड में टाइप पैरामीटर का नाम वहीं है:

// Type member version
class MySuite extends FixtureSuite with StringBuilderFixture {
  type FixtureParam = StringBuilder
  // ...
}

बाद के मामले में, कोड के पाठक देख सकते हैं कि StringBuilder"स्थिरता पैरामीटर" प्रकार है।
उन्हें अभी भी यह पता लगाने की आवश्यकता होगी कि "स्थिरता पैरामीटर" का क्या मतलब है, लेकिन वे कम से कम दस्तावेज में देखे बिना प्रकार का नाम प्राप्त कर सकते हैं।


61
जब आप आते हैं और ऐसा करते हैं तो मुझे स्काला के सवालों का जवाब देकर कर्म अंक कैसे प्राप्त करने चाहिए ??? :-)
डैनियल सी। सोबरल

7
हाय डैनियल: मुझे लगता है कि पैरामीरिजेशन पर अमूर्त प्रकार के लाभों को दर्शाने के लिए ठोस उदाहरण होने चाहिए। इस सूत्र में कुछ पोस्ट करना एक अच्छी शुरुआत होगी;) मुझे पता है कि मैं इसे बढ़ाऊंगा।
वॉनसी

1
क्या आपको लगता है कि निम्नलिखित एक उचित सारांश है: सार प्रकार का उपयोग 'है-एक' या 'उपयोग-एक' रिश्तों में किया जाता है (जैसे एक गाय घास खाती है) जहां जेनेरिक आमतौर पर 'रिश्तों' (जैसे सूची की सूची)
thatismatt

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

1
स्वयं पर ध्यान दें: इस मई 2010 ब्लॉग पोस्ट को भी देखें: daily-scala.blogspot.com/2010/05/…
VonC

37

जब मैं स्काला के बारे में पढ़ रहा था तो मेरा भी यही सवाल था।

जेनरिक का उपयोग करने का लाभ यह है कि आप एक प्रकार का परिवार बना रहे हैं। कोई भी उपवर्ग करने की आवश्यकता होगी Buffer, वे सिर्फ उपयोग कर सकते हैं Buffer[Any], Buffer[String]आदि

यदि आप एक सार प्रकार का उपयोग करते हैं, तो लोग एक उपवर्ग बनाने के लिए मजबूर होंगे। लोगों को कक्षाओं की आवश्यकता होगी AnyBuffer, जैसे StringBuffer, आदि।

आपको यह तय करने की आवश्यकता है कि आपकी विशेष आवश्यकता के लिए कौन सा बेहतर है।


18
इस मोर्चे पर Buffer { type T <: String }Buffer { type T = String }
एमएमएम थिन्स में

21

आप कस्टम टेम्प्लेट स्थापित करने के लिए टाइप पैरामीटर के साथ संयोजन में अमूर्त प्रकार का उपयोग कर सकते हैं।

मान लें कि आपको तीन जुड़े लक्षणों के साथ एक पैटर्न स्थापित करने की आवश्यकता है:

trait AA[B,C]
trait BB[C,A]
trait CC[A,B]

जिस तरह से टाइप पैरामीटर में उल्लिखित तर्क एए, बीबी, सीसी स्वयं सम्मानजनक हैं

आप कुछ प्रकार के कोड के साथ आ सकते हैं:

trait AA[B<:BB[C,AA[B,C]],C<:CC[AA[B,C],B]]
trait BB[C<:CC[A,BB[C,A]],A<:AA[BB[C,A],C]]
trait CC[A<:AA[B,CC[A,B]],B<:BB[CC[A,B],A]]

जो टाइप पैरामीटर बॉन्ड के कारण इस सरल तरीके से काम नहीं करेगा। आपको इसे सही ढंग से प्राप्त करने के लिए सहसंयोजक बनाने की आवश्यकता है

trait AA[+B<:BB[C,AA[B,C]],+C<:CC[AA[B,C],B]]
trait BB[+C<:CC[A,BB[C,A]],+A<:AA[BB[C,A],C]]
trait CC[+A<:AA[B,CC[A,B]],+B<:BB[CC[A,B],A]]

यह एक नमूना संकलित करेगा लेकिन यह विचरण नियमों पर मजबूत आवश्यकताएं निर्धारित करता है और कुछ अवसरों में इसका उपयोग नहीं किया जा सकता है

trait AA[+B<:BB[C,AA[B,C]],+C<:CC[AA[B,C],B]] {
  def forth(x:B):C
  def back(x:C):B
}
trait BB[+C<:CC[A,BB[C,A]],+A<:AA[BB[C,A],C]] {
  def forth(x:C):A
  def back(x:A):C
}
trait CC[+A<:AA[B,CC[A,B]],+B<:BB[CC[A,B],A]] {
  def forth(x:A):B
  def back(x:B):A
}

संकलक विचरण जाँच त्रुटियों के गुच्छा के साथ आपत्ति करेगा

उस स्थिति में आप अतिरिक्त विशेषता और पैराट्राइज़ के अन्य प्रकार की सभी आवश्यकताओं को उस पर एकत्रित कर सकते हैं

//one trait to rule them all
trait OO[O <: OO[O]] { this : O =>
  type A <: AA[O]
  type B <: BB[O]
  type C <: CC[O]
}
trait AA[O <: OO[O]] { this : O#A =>
  type A = O#A
  type B = O#B
  type C = O#C
  def left(l:B):C
  def right(r:C):B = r.left(this)
  def join(l:B, r:C):A
  def double(l:B, r:C):A = this.join( l.join(r,this), r.join(this,l) )
}
trait BB[O <: OO[O]] { this : O#B =>
  type A = O#A
  type B = O#B
  type C = O#C
  def left(l:C):A
  def right(r:A):C = r.left(this)
  def join(l:C, r:A):B
  def double(l:C, r:A):B = this.join( l.join(r,this), r.join(this,l) )
}
trait CC[O <: OO[O]] { this : O#C =>
  type A = O#A
  type B = O#B
  type C = O#C
  def left(l:A):B
  def right(r:B):A = r.left(this)
  def join(l:A, r:B):C
  def double(l:A, r:B):C = this.join( l.join(r,this), r.join(this,l) )
}

अब हम वर्णित पैटर्न के लिए ठोस प्रतिनिधित्व लिख सकते हैं, बाएं को परिभाषित कर सकते हैं और सभी वर्गों में तरीकों को जोड़ सकते हैं और मुफ्त में सही और डबल प्राप्त कर सकते हैं

class ReprO extends OO[ReprO] {
  override type A = ReprA
  override type B = ReprB
  override type C = ReprC
}
case class ReprA(data : Int) extends AA[ReprO] {
  override def left(l:B):C = ReprC(data - l.data)
  override def join(l:B, r:C) = ReprA(l.data + r.data)
}
case class ReprB(data : Int) extends BB[ReprO] {
  override def left(l:C):A = ReprA(data - l.data)
  override def join(l:C, r:A):B = ReprB(l.data + r.data)
}
case class ReprC(data : Int) extends CC[ReprO] {
  override def left(l:A):B = ReprB(data - l.data)
  override def join(l:A, r:B):C = ReprC(l.data + r.data)
}

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

वे एक-दूसरे को तालमेल देते हैं और जटिल अमूर्तता पैदा करने के लिए संयोजन में उपयोग किया जा सकता है जो केवल उनमें से एक के साथ व्यक्त नहीं किया जा सकता है।


0

मुझे लगता है कि यहां बहुत अंतर नहीं है। टाइप एब्सट्रैक्ट सदस्यों को केवल अस्तित्वगत प्रकार के रूप में देखा जा सकता है जो कुछ अन्य कार्यात्मक भाषाओं में रिकॉर्ड प्रकारों के समान है।

उदाहरण के लिए, हमारे पास:

class ListT {
  type T
  ...
}

तथा

class List[T] {...}

फिर ListTजैसा है वैसा ही है List[_]। प्रकार के सदस्यों का विश्वास है कि हम स्पष्ट ठोस प्रकार के बिना वर्ग का उपयोग कर सकते हैं और कई प्रकार के मापदंडों से बच सकते हैं।

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