2010-12-01 14 views
8

इस स्काला कोड को देखते हुए:बाई-पैरामीटर के साथ केस से अलग-अलग पैरामीटर के साथ ओवरलोडिंग के मामले में स्कैला का व्यवहार क्यों है?

object test { 

    def byval(a: Int) = println("Int") 
    def byval(a: Long) = println("Long") 

    def byname(a: => Int) = println("=> Int") 
    def byname(a: => Long) = println("=> Long") 

    def main(args: Array[String]) { 
     byval(5) 
     byname(5) 
    } 
} 

कॉल byval (5) सही ढंग से संकलित, लेकिन byname संकलन करने में विफल रहता है:

ambiguous reference to overloaded definition 

क्यों? मैं ओवरलोडिंग के संबंध में उप-मूल्य और उप-पैरामीटर के लिए एक ही व्यवहार का निरीक्षण करने की अपेक्षा करता हूं ... इसे कैसे ठीक किया जा सकता है?

+0

यह एक बग हो सकती है ... – soc

उत्तर

13

ऐसा इसलिए है क्योंकि JVM "उप-नाम" पैरामीटर का समर्थन नहीं करता है, इसलिए स्कैला को इसे किसी अन्य तरीके से कार्यान्वित करना है। => X वास्तव में Function0[X] पर संकलित करता है, जो Function0[Object] तक मिटा देता है, जिससे स्कैला के लिए दो विधियों को अलग करना असंभव हो जाता है जो केवल उप-नाम पैरामीटर के अपेक्षित प्रकार से अलग होते हैं।

+0

धन्यवाद डैनियल, इस क्यों बताता है। अब यह कैसे काम किया जा सकता है (यदि संभव हो तो)? –

+1

@ जेपीपी यह एक प्रश्न है जिसे पहले पूछा गया है। एक आसान तरीका पहला तर्क अनिवार्य बनाना होगा और vararg का हिस्सा नहीं होगा। अन्य तरीकों में अंतर्निहित पैरामीटर शामिल हैं, लेकिन मुझे सटीक चाल याद नहीं है। –

+0

@ जेपीपी: इस विशेष मामले में ओवरलोडिंग का उपयोग न करें। –

6

अधिक भार (क्या पहले कहा जा चुका है के अलावा), आप विभिन्न विधि के नाम का उपयोग नहीं करना चाहते हैं, तो बिना संभव वैकल्पिक हल:

def byname[A](a: => A)(implicit manifest:Manifest[A]) = 
manifest.erasure match { 
    case erasure if(erasure.isAssignableFrom(classOf[Long])) => println("=> Long") 
    case erasure if(erasure.isAssignableFrom(classOf[Int])) => println("=> Int") 
}