2012-07-15 47 views
7

मैं अब देखते हैं कि वहाँ एक संबंधित सवाल पूछ क्या इन ऑपरेटरों (<: <, <% <, =: =) है कि यहां कार्य करें:<: <, <% <, =: = कंपाइलर में काम का स्केल कार्यान्वयन वास्तव में कैसे करता है?

What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?

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

class Foo[T](a: T) { 
    def splitit(implicit ev: T <:< String) = a split " " 
} 

लेकिन यह वास्तव में संकलक में कैसे काम करता है? क्या इन ऑपरेटरों के लिए कुछ जादू कंपाइलर समर्थन है, और यदि नहीं, तो अंतर्निहित तंत्र क्या है जो इसे परिभाषा से इस प्रकार के रिश्ते को कम करने की अनुमति देता है? (क्या यह तंत्र विशेष रूप से इन ऑपरेटरों को काम करने की अनुमति देने के लिए जोड़ा गया था, और इन विशेष ऑपरेटरों के लिए यह कितना विशिष्ट है?) ऐसा लगता है कि आप इस तरह के एक अतिरिक्त निहित पैरामीटर डाल सकते हैं जो कि किसी प्रकार के कंपाइलर की व्याख्या को किसी भी तरह बदलता है।

+2

उनके लिए स्रोत https://github.com/scala/scala/blob/v2.9.2/src/library/scala/Predef.scala#L394 – pedrofurla

उत्तर

8

कार्यान्वयन थोड़ा मुश्किल है, लेकिन जादुई कुछ भी नहीं है।

वहाँ Predef में एक अंतर्निहित विधि जब आप अपने विधि को लागू करने की कोशिश है जो किसी भी A

implicit def conforms[A]: A <:< A 

के लिए प्रकार A <:< A के एक मूल्य प्रदान कर सकते हैं, यह प्रकार T <:< String का एक अंतर्निहित मूल्य के लिए दिखता है। संकलक यह देखने के लिए जांच करेगा कि conforms[T] मान्य मान है या नहीं। मान लें कि TNothing है तो दायरे में एक अंतर्निहित मूल्य Nothing <:< Nothing होगा जो आपके विधि कॉल को संकलित करने की अनुमति देगा। तरीके के कारण <:< को

sealed abstract class <:<[-From, +To] 

From परिभाषित किया गया है अप भिन्न करने की अनुमति दी है और To नीचे भिन्न करने की अनुमति दी है। तो Nothing <:< Nothing अभी भी वैध Nothing <:< String है क्योंकि NothingString का उप प्रकार है। String <:< String एक वैध Nothing <:< String भी होगा क्योंकि StringNothing का सुपरटेप है (लेकिन संकलक हमेशा पहले प्रकार को चुनता है)।

आप इस पर String के तरीकों कॉल कर सकते हैं क्योंकि <:< भी Function1 उर्फ ​​=> प्रदान करता है और String करने के लिए T से एक अंतर्निहित रूपांतरण है, जो मूल रूप से एक सुरक्षित डाली कर समाप्त होता है के रूप में कार्य करता है।

=:= वही बात है, सिवाय इसके कि इसे किसी भिन्न भिन्नता के बिना परिभाषित किया गया है, इसलिए प्रकार बिल्कुल मेल खाते हैं।

<%<<:< तरह परिभाषित किया गया है, लेकिन अंतर्निहित विधि थोड़ी अलग है, यह एक दृश्य के लिए बाध्य

implicit def conformsOrViewsAs[A <% B, B]: A <%< B 

यह भी हटा दिया गया है निर्दिष्ट करने के लिए अन्य पैरामीटर कहते हैं।

+0

धन्यवाद!निम्नलिखित यह समझाने की कुंजी है कि कंपाइलर आपको स्ट्रिंग विधियों (या जो भी) को कॉल करने देता है: _ आप उस पर स्ट्रिंग के तरीकों को कॉल कर सकते हैं क्योंकि <: <भी => उर्फ ​​फ़ंक्शन 1 बढ़ाता है और टी से स्ट्रिंग तक एक अंतर्निहित रूपांतरण के रूप में कार्य करता है, जो मूल रूप से एक सुरक्षित कलाकार कर समाप्त होता है ._ –

संबंधित मुद्दे