2012-10-08 12 views
6
object ScalaTrueRing { 
    def rule = println("To rule them all") 
} 
कोड के इस टुकड़े

जावा बाइट कोड में संकलित किया जाएगा, अगर मैं इसे डिकंपाइल, तो बराबर जावा कोड इस के समान है:एक स्काला साथी ऑब्जेक्ट दो वर्गों (जावा और .NET कंपेलरों दोनों) में संकलित क्यों है?

public final class JavaTrueRing 
{ 
    public static final void rule() 
    { 
    ScalaTrueRing..MODULE$.rule(); 
    } 
} 


/* */ public final class JavaTrueRing$ 
/* */ implements ScalaObject 
/* */ { 
/* */ public static final MODULE$; 
/* */ 
/* */ static 
/* */ { 
/* */  new(); 
/* */ } 
/* */ 
/* */ public void rule() 
/* */ { 
/* 11 */  Predef..MODULE$.println("To rule them all"); 
/* */ } 
/* */ 
/* */ private JavaTrueRing$() 
/* */ { 
/* 10 */  MODULE$ = this; 
/* */ } 
/* */ } 

यह दो वर्गों में संकलित किया गया है, और अगर मैं स्काला का उपयोग .net संकलक, यह MSIL कोड में संकलित किया जाएगा, और बराबर सी # कोड इस तरह है:

public sealed class ScalaTrueRing 
{ 
    public static void rule() 
    { 
     ScalaTrueRing$.MODULE$.rule(); 
    } 
} 

[Symtab] 
public sealed class ScalaTrueRing$ : ScalaObject 
{ 
    public static ScalaTrueRing$ MODULE$; 
    public override void rule() 
    { 
     Predef$.MODULE$.println("To rule them all"); 
    } 
    private ScalaTrueRing$() 
    { 
     ScalaTrueRing$.MODULE$ = this; 
    } 
    static ScalaTrueRing$() 
    { 
     new ScalaTrueRing$(); 
    } 
} 

यह भी दो वर्गों में संकलित किया है।

स्कैला कंपाइलर्स (जावा के लिए एक और .NET के लिए एक) ऐसा क्यों करता है? यह स्थिर नियम विधि में केवल println विधि क्यों नहीं कहता है?

+0

तो, 'JavaTrueRing $' वर्ग कहां से आता है? –

+0

@ द एलिट जेंटलमैन इसका असली नाम स्कैलाट्रूइंग $ है, मैंने नाम बदलकर स्पष्ट रूप से दिखाया कि यह जावा कोड है। मैंने कक्षा फ़ाइल को संकुचित कर लिया और उसे मिला। – CuiPengFei

उत्तर

8

स्कैला में यह समझना महत्वपूर्ण है कि object वास्तव में एक प्रथम श्रेणी का नागरिक है: यह एक वास्तविक उदाहरण है जिसे किसी अन्य वस्तु के रूप में पारित किया जा सकता है। उदाहरण द्वारा:

trait Greetings { 
    def hello() { println("hello") } 
    def bye() { println("bye") } 
} 

object FrenchGreetings extends Greetings { 
    override def hello() { println("bonjour") } 
    override def bye() { println("au revoir") } 
} 

def doSomething(greetings: Greetings) { 
    greetings.hello() 
    println("... doing some work ...") 
    greetings.bye() 
} 

doSomething(FrenchGreetings) 

स्थिर तरीकों के साथ विपरीत, हमारे सिंगलटन वस्तु पूर्ण बहुरूपी beheviour है।

bonjour 
... doing some work ... 
au revoir 

तो object कार्यान्वयन जरूरी एक उचित वर्ग होना चाहिए: doSomething वास्तव में हमारे ओवरराइड hello और bye विधियों, और नहीं डिफ़ॉल्ट कार्यान्वयन कॉल करेंगे। लेकिन जावा के साथ इंटरऑपरेबिलिटी के लिए, कंपाइलर भी स्थिर विधियों को उत्पन्न करता है जो कक्षा के अद्वितीय उदाहरण (MODULE$) को आगे बढ़ाते हैं (JavaTrueRing.rule() देखें)। इस तरह, एक जावा प्रोग्राम सिंगलटन ऑब्जेक्ट के तरीकों को सामान्य स्थैतिक विधि के रूप में एक्सेस कर सकता है। अब आप पूछ सकते हैं कि क्यों स्कैला उसी विधि में स्थिर विधि फ़ॉरवर्डर्स को उदाहरण विधियों के रूप में नहीं रखता है। यह हमें की तरह कुछ देना होगा:

public final class JavaTrueRing implements ScalaObject { 
    public static final MODULE$; 

    static { 
    new JavaTrueRing(); 
    } 

    public void rule() { 
    Predef.MODULE$.println("To rule them all"); 
    } 

    private JavaTrueRing() { 
    MODULE$ = this; 
    } 

    // Forwarders 
    public static final void rule() { 
    MODULE$.rule(); 
    } 
} 

मुझे विश्वास है कि मुख्य कारण यह रूप में सरल नहीं किया जा सकता है, क्योंकि JVM में आप एक ही कक्षा में एक उदाहरण विधि और एक स्थिर विधि एक ही wth नहीं हो सकता हस्ताक्षर। हालांकि अन्य कारण हो सकते हैं।

1

यह Blog entry "A Look at How Scala Compiles to Java" आपके प्रश्न का उत्तर चाहिए

आमतौर className $ .class इनर क्लासों के परिणाम हैं - स्काला स्पष्ट रूप से थोड़ा अलग है।

+1

कि ब्लॉग पोस्ट बताता है कि स्कैला कंपाइलर क्या करता है, लेकिन यह क्यों नहीं समझाता है। स्कैला कंपाइलर क्यों स्थिर नियम विधि में println विधि को कॉल नहीं करता है? – CuiPengFei

3

"प्रोग्रामिंग इन स्कैला" से पैराफ्रेशिंग - क्योंकि एक स्कैला साथी ऑब्जेक्ट (सिंगलटन ऑब्जेक्ट) स्थिर विधियों के धारक से अधिक है। एक अलग जावा क्लास का उदाहरण होने के कारण, यह डेवलपर को सिंगलटन ऑब्जेक्ट्स और मिक्स-इन लक्षणों का विस्तार करने की अनुमति देता है। यह स्थैतिक तरीकों से नहीं किया जा सकता है।

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