स्केल में लक्षण "हीरे की त्रुटि" से कैसे बचें?


16

(नोट: मैंने स्पष्ट कारणों के लिए शीर्षक में 'समस्या' के बजाय 'त्रुटि' का उपयोग किया है ..;))।

मैंने स्काला में ट्रेट्स पर कुछ बुनियादी रीडिंग की। वे जावा या सी # में इंटरफेस के समान हैं, लेकिन वे एक विधि के डिफ़ॉल्ट कार्यान्वयन के लिए अनुमति देते हैं।

मैं सोच रहा था: क्या यह "हीरे की समस्या" का मामला नहीं बन सकता है, यही वजह है कि कई भाषाएं पहले स्थान पर कई विरासत से बचती हैं?

यदि हां, तो स्काला इसे कैसे संभालती है?


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

2
@gnat: यह एक वैचारिक प्रश्न है, ठोस समस्या प्रश्न नहीं है। यदि वह पूछ रहा था कि "मेरे पास स्काला में यह वर्ग है और यह मुझे समस्याएं दे रहा है जो मुझे लगता है कि डायमंड समस्या से संबंधित हो सकती है, तो मैं इसे कैसे ठीक करूं?" तब आपकी टिप्पणी उचित होगी, लेकिन तब प्रश्न SO पर होगा। : पी
मेसन व्हीलर

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

7
उस कथन को पढ़ना आपको बताता नहीं है कि यह कैसे करता है।
माइकल ब्राउन

जवाबों:


22

हीरे की समस्या यह तय करने में असमर्थता है कि किस विधि को चुनना है। स्केला ने इसे परिभाषित करते हुए कहा कि भाषा विनिर्देशों के भाग के रूप में चुनने के लिए कौन सा कार्यान्वयन ( इस विकिपीडिया लेख में स्काला के बारे में भाग पढ़ें )।

बेशक, एक ही क्रम परिभाषा का उपयोग कक्षा के कई उत्तराधिकार में भी किया जा सकता है, इसलिए लक्षण के साथ परेशान क्यों करें?

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

यदि B और C को A और D विरासत में मिलते हैं, तो B और C, और B और C दोनों के निर्माता A के कंस्ट्रक्टर को कॉल करते हैं, जबकि D का कंस्ट्रक्टर A के कंस्ट्रक्टर को दो बार कॉल करेगा। स्केल को चुनने के लिए कौन से कार्यान्वयन को परिभाषित करना विधियों के साथ किया गया क्योंकि यहां काम नहीं करेगा क्योंकि दोनों बी और सी के निर्माता को बुलाया जाना चाहिए।

लक्षण इस समस्या से बचते हैं क्योंकि उनके पास निर्माता नहीं हैं।


1
कंस्ट्रक्टरों को एक बार और केवल एक बार कॉल करने के लिए C3 के रैखिककरण का उपयोग करना संभव है - यही कारण है कि पायथन एकाधिक वंशानुक्रम करता है। मेरे सिर के ऊपर से D <B | C <a हीरे का D -> B -> C -> A. है। इसके अलावा, एक Google खोज ने मुझे दिखाया है कि स्काला लक्षण में परिवर्तनशील चर हो सकते हैं, इसलिए निश्चित रूप से ए है कंस्ट्रक्टर कहीं वहाँ? लेकिन अगर यह हुड के तहत रचना का उपयोग कर रहा है (मुझे नहीं पता, स्केला का इस्तेमाल कभी नहीं किया गया) यह देखना मुश्किल नहीं है कि बी और सी ए के उदाहरण पर साझा कर सकते हैं ...
डोभाल

... लक्षण बस एक बहुत ही संक्षिप्त तरीके की तरह प्रतीत होता है कि सभी बॉयलरप्लेट को व्यक्त करने के लिए जो इंटरफ़ेस विरासत और संयोजन + प्रतिनिधिमंडल में जाता है, जो व्यवहार का पुन: उपयोग करने का सही तरीका है।
डोभाल

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

एक और सवाल यह है कि C ++ ने हीरे की समस्या के लिए समझदार नीति क्यों नहीं चुनी?
उपयोगकर्ता

21

स्केला हीरे की समस्या को "विशेषता रेखीयकरण" कहकर टाल देता है। मूल रूप से, यह आपके द्वारा दाएं से बाएं तक फैले लक्षणों में विधि के कार्यान्वयन को देखता है। सरल उदाहरण:

trait Base {
   def op: String
}

trait Foo extends Base {
   override def op = "foo"
}

trait Bar extends Base {
   override def op = "bar"
}

class A extends Foo with Bar
class B extends Bar with Foo

(new A).op
// res0: String = bar

(new B).op
// res1: String = foo

यह कहने के बाद कि, यह दिखने वाले लक्षणों की सूची आपके द्वारा स्पष्ट रूप से दिए गए लोगों से अधिक हो सकती है, क्योंकि वे अन्य लक्षणों का विस्तार कर सकते हैं। यहाँ एक विस्तृत विवरण दिया गया है: स्टैकेबल संशोधनों के रूप में लक्षण और यहाँ रैखिककरण का एक और पूर्ण उदाहरण: एकाधिक वंशानुक्रम क्यों नहीं?

मेरा मानना ​​है कि अन्य प्रोग्रामिंग भाषाओं में इस व्यवहार को कभी-कभी "विधि समाधान आदेश" या "एमआरओ" के रूप में संदर्भित किया जाता है।

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