2013-02-13 21 views
13

स्कैला 2.10 मूल्य वर्ग प्रस्तुत करता है, जिसे आप अपनी कक्षा AnyVal बढ़ाकर निर्दिष्ट करते हैं। मूल्य वर्गों पर कई प्रतिबंध हैं, लेकिन उनके बड़े फायदों में से एक यह है कि वे एक नई कक्षा बनाने के दंड के बिना विस्तार विधियों की अनुमति देते हैं: जब तक कि मुक्केबाजी की आवश्यकता न हो। मूल्य वर्ग को सरणी में रखने के लिए, यह केवल पुरानी कक्षा है और विधियों का एक सेट है जो कक्षा को पहले पैरामीटर के रूप में लेता है। इस प्रकार,आप बिना ओवरहेड के मूल्य वर्गों को कैसे समृद्ध करते हैं?

implicit class Foo(val i: Int) extends AnyVal { 
    def +*(j: Int) = i + j*j 
} 

कुछ है कि i + j*j लेखन अपने आप को (एक बार JVM विधि कॉल inlines) से अधिक नहीं महंगा हो सकता है के लिए unwraps।

दुर्भाग्य से, SIP-15 जो मूल्य वर्गों का वर्णन में प्रतिबंध में से एक है

  1. सी के अंतर्निहित प्रकार एक मूल्य वर्ग नहीं हो सकता।

आप एक मूल्य वर्ग है कि आप पर कहते हैं, अपने हाथों को प्राप्त कर सकते हैं एक तरह से मुक्केबाजी के उपरि बिना टाइप सुरक्षित इकाइयों प्रदान करने के लिए (जब तक आप वास्तव में इसकी जरूरत) के रूप में है, तो:

class Meter(val meters: Double) extends AnyVal { 
    def centimeters = meters*100.0    // No longer type-safe 
    def +(m: Meter) = new Meter(meters+m.meters) // Only works with Meter! 
} 

तो ऑब्जेक्ट-निर्माण ओवरहेड के बिना Meter को समृद्ध करने का कोई तरीका है? एसआईपी -15 में प्रतिबंध स्पष्ट

implicit class RichMeter(m: Meter) extends AnyVal { ... } 

दृष्टिकोण को रोकता है।

उत्तर

14

मूल्य वर्गों को बढ़ाने के लिए, आपको अंतर्निहित प्रकार को पुनः प्राप्त करने की आवश्यकता है। चूंकि मूल्य वर्गों को उनके लिपटे प्रकार के सुलभ होने की आवश्यकता होती है (val i ऊपर केवल i नहीं), आप हमेशा ऐसा कर सकते हैं। आप आसानी से implicit class शॉर्टकट का उपयोग नहीं कर सकते हैं, लेकिन आप अभी भी निहित रूपांतरण लम्बाई जोड़ सकते हैं। तो, आप की तरह

class RichMeter(val meters: Double) extends AnyVal { 
    def -(m: Meter) = new Meter(meters - m.meters) 
} 
implicit def EnrichMeters(m: Meter) = new RichMeter(m.meters) 

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

(भी ध्यान रखें कि आप एक चेतावनी मिल जाएगा जब तक आप import language.implicitConversions।)

परिशिष्ट: स्काला 2.11+ में, आप कर सकते हैं val निजी; जिन मामलों के लिए यह किया गया था, आप इस चाल का उपयोग करने में सक्षम नहीं होंगे।

+0

यह एसआईपी -15 की निगरानी की तरह लगता है, क्योंकि यह सीधे सहेजे गए वर्बोजिटी 'निहित वर्ग' प्रदान करता है। क्या अधिक जानकारी के लिए कोई लिंक हैं कि क्यों मूल्य वर्ग में अंतर्निहित प्रकार के रूप में मूल्य वर्ग नहीं हो सकता है? (संकलक सीमाएं, कार्यान्वयन की जटिलता, या अन्यथा) –

+0

@AlexDiCarlo - मूल्य वर्गों पर बहुत से प्रतिबंध हैं जो तर्कसंगत रूप से आवश्यक नहीं हैं, इसलिए मेरी धारणा यह है कि कार्यान्वयन को सरल बनाने के लिए यह किया गया था। –