2009-04-15 16 views
109

बाइटकोड स्तर पर लागू स्कैला में पैटर्न मिलान कैसे है?बाइटकोड स्तर पर लागू स्कैला में पैटर्न मिलान कैसे है?

क्या यह if (x instanceof Foo) संरचनाओं की एक श्रृंखला की तरह है, या कुछ और? इसके प्रदर्शन प्रभाव क्या हैं?

उदाहरण के लिए, निम्नलिखित कोड दिया गया है (Scala By Example पृष्ठ 46-48 से), eval विधि के बराबर जावा कोड कैसा दिखता है?

abstract class Expr 
case class Number(n: Int) extends Expr 
case class Sum(e1: Expr, e2: Expr) extends Expr 

def eval(e: Expr): Int = e match { 
    case Number(x) => x 
    case Sum(l, r) => eval(l) + eval(r) 
} 

पीएस मैं जावा बाइटकोड पढ़ सकता हूं, इसलिए बाइटकोड प्रतिनिधित्व मेरे लिए काफी अच्छा होगा, लेकिन शायद अन्य पाठकों के लिए यह बेहतर होगा कि यह जावा कोड जैसा कैसा लगेगा।

पी.पी.एस. क्या पुस्तक Programming in Scala स्कैला को कार्यान्वित करने के तरीके के बारे में और इसी तरह के प्रश्नों का उत्तर देती है? मैंने किताब का आदेश दिया है, लेकिन यह अभी तक नहीं पहुंचा है।

+0

आप उदाहरण को संकलित क्यों नहीं करते हैं और जावा बाइटकोड डिस्सेबलर के साथ इसे अलग करते हैं? – Zifre

+0

मैं शायद ऐसा करूंगा, जब तक कि कोई पहले कोई अच्छा जवाब न दे। लेकिन अभी मैं कुछ नींद लेना चाहता हूं। ;) –

+22

प्रश्न अन्य पाठकों के लिए उपयोगी है! – djondal

उत्तर

85

निम्न स्तर एक disassembler के साथ पता लगाया जा सकता है, लेकिन संक्षिप्त उत्तर है कि यह का एक समूह है है अगर/elses जहां विधेय पैटर्न पर निर्भर करता है

case Sum(l,r) // instance of check followed by fetching the two arguments and assigning to two variables l and r but see below about custom extractors 
case "hello" // equality check 
case _ : Foo // instance of check 
case x => // assignment to a fresh variable 
case _ => // do nothing, this is the tail else on the if/else 

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

इसके अलावा, आप डिफ़ॉल्ट कक्षाओं के बजाय या कक्षा वर्गों के लिए स्कैला उपयोग के बजाय अपने स्वयं के कस्टम निकालने वाले लिख सकते हैं। यदि आप करते हैं, तो पैटर्न मिलान की लागत एक्स्ट्रेक्टर जो भी करता है उसकी लागत होती है। http://lamp.epfl.ch/~emir/written/MatchingObjectsWithPatterns-TR.pdf

70

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

def eval(e: Expr): Int = { 
    <synthetic> val temp10: Expr = e; 
    if (temp10.$isInstanceOf[Number]()) 
    temp10.$asInstanceOf[Number]().n() 
    else 
    if (temp10.$isInstanceOf[Sum]()) 
     { 
     <synthetic> val temp13: Sum = temp10.$asInstanceOf[Sum](); 
     Main.this.eval(temp13.e1()).+(Main.this.eval(temp13.e2())) 
     } 
    else 
     throw new MatchError(temp10) 
}; 
28

संस्करण 2.8 के बाद से, स्काला @switch एनोटेशन पड़ा है: यहाँ कोड का टुकड़ा दिया था के लिए प्रासंगिक scalac -print उत्पादन है। लक्ष्य यह सुनिश्चित करना है कि सशर्त if कथन की श्रृंखला के बजाय पैटर्न मिलान tableswitch or lookupswitch में संकलित किया जाएगा।

+5

नियमित रूप से @switch को नियमित रूप से चुनने के लिए कब? –

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