2015-12-07 5 views
6

में लागू अमूर्त वर्ग कन्स्ट्रक्टर पैरामीटर और विरासत मैं स्कैला के लिए बिल्कुल नया हूं और निहित रूपांतरणों और मानकों को सीखने और समझने की कोशिश कर रहा हूं और मुझे एक परिदृश्य का सामना करना पड़ा है जो मुझे भ्रमित लगता है।स्कैला

संदर्भ के लिए, मैं एक अक्का आवेदन में निर्भरता इंजेक्शन करने के लिए स्काल्डी का उपयोग कर रहा हूं और कई इंजेक्शन योग्य अभिनेताओं को एक अमूर्त वर्ग से प्राप्त करना चाहता हूं। मेरा मानना ​​है कि मैं अमूर्त वर्ग को एक विशेषता सटीक बनाने में असमर्थ हूं क्योंकि हमें ढांचे का लाभ उठाने के लिए एक निर्माता तर्क के माध्यम से एक अंतर्निहित Injector उपलब्ध कराने की आवश्यकता है।

एक बहुत ही काल्पनिक उदाहरण है कि व्यवहार है कि मैं देख रहा हूँ दर्शाती है इस प्रकार है:

class SecretSauce {} 

abstract class Base(implicit secretSauce: SecretSauce) {} 

class Concrete extends Base {} 

object Example extends App { 
    ... // Setup Actor system, etc, etc 
    implicit val secretSauce: SecretSauce = new SecretSauce() 
} 

मैं चीजों को काम करने के लिए, लेकिन इसके बजाय मैं एक संकलन त्रुटि मिलती है उम्मीद कर रहा था:

Unspecified value parameter secretSauce. 
class Concrete extends Base { 
      ^

मैं तो कंक्रीट वर्ग में अंतर्निहित पैरामीटर जोड़ें, जैसे चीजें काम करती हैं:

class Concrete(implicit secretSauce: SecretSauce) extends Base {} 

मैं टी मेरे भ्रम को झुकाएं कि कैसे अंतर्निहित पैरामीटर काम करते हैं - ऐसी स्थितियों में जैसे कि मैं वर्णन कर रहा हूं, क्या उन्हें बाल वर्गों द्वारा विरासत में नहीं मिला है? क्या कोई व्यक्ति मेरे उदाहरण में क्या हो रहा है या मुझे संदर्भ में इंगित करता है जो चीजों को साफ़ करने में मदद कर सकता है?

धन्यवाद!

उत्तर

2

सटीक नियम है कि निर्धारित implicits तरह का जटिल हैं के लिए जहां स्काला संकलक है, लेकिन ज्यादातर स्थितियों में आप ही के बारे में दो स्थानों पर निहित मूल्यों से आ सकता है सोचने की जरूरत:

  1. वर्तमान क्षेत्र।
  2. सहयोगी वस्तुओं को किसी भी प्रकार के लिए शामिल किया गया है।,

    class SecretSauce {} 
    
    abstract class Base(implicit secretSauce: SecretSauce) {} 
    
    object Example extends App { 
        implicit val secretSauce: SecretSauce = new SecretSauce() 
    
        class Concrete extends Base {} 
    } 
    

    अपने संस्करण में हालांकि, जब संकलक इस लाइन के लिए हो जाता है:

इसका मतलब यह है इस संकलन होगा:

class SecretSauce {} 

object SecretSauce { 
    implicit val secretSauce: SecretSauce = new SecretSauce() 
} 

abstract class Base(implicit secretSauce: SecretSauce) {} 

object Example extends App { 
    class Concrete extends Base {} 
} 

या इस

class Concrete extends Base {} 

यह पता चलेगा कि इसे एक अंतर्निहित SecretSauce वीए खोजने की आवश्यकता है लुई, और यह उस पंक्ति पर के दायरे में अंतर्निहित मूल्यों पर पहली बार दिखाई देगा और SecretSauce सहयोगी वस्तु (यदि यह मौजूद है) में अगला होगा। यह या तो नहीं मिलता है, इसलिए यह आपके कोड को संकलित करने से इंकार कर देता है।

+0

आह, मुझे लगता है कि नियमों का आसवन काफी मदद करता है। उस मामले में एक संकलन त्रुटि क्यों नहीं फेंक दी जाती है जहां ठोस वर्ग में निहित तर्क डुप्लिकेट किया जाता है? उदाहरण के लिए क्लास कंक्रीट (निहित गुप्त सॉस: सीक्रेटसाउस) बेस {} ' बढ़ाता है जिस तरह से मैंने इसे अपने कोड में सेट किया है, निहित मूल्य अभी भी दायरे में नहीं है और न ही यह एक साथी वस्तु में है, है ना? क्या यहां मेरी गुंजाइश की समझ है? – simonl

+0

@ सिमोनल जब आप 'कंक्रीट' कन्स्ट्रक्टर को अंतर्निहित पैरामीटर जोड़ते हैं, तो वह अंतर्निहित माता-पिता कन्स्ट्रक्टर को कॉल के दायरे में होगा। कक्षा परिभाषाओं और रचनाकारों के लिए स्कैला का वाक्यविन्यास यह थोड़ा अनजान बनाता है, लेकिन यह काम करता है। –

1

अंतर्निहित पैरामीटर से "का समाधान" हो:

  • Implicits वर्तमान क्षेत्र में परिभाषित
  • स्पष्ट आयात
  • वाइल्डकार्ड आयात

आदेश में जहाँ तक मैं समझता हूँ class Concrete परिभाषित करने के लिए , निहित परिभाषित या आयात करने की जरूरत है।

मुझे this SO answer में एक बहुत अच्छी व्याख्या मिलती है।