2012-05-20 15 views
6

मैं स्केल के प्रीडिफ क्लास में एक स्ट्रिंग के साथ दूसरे तर्क के रूप में आवश्यकता विधि, उदाहरण के लिए आवश्यकता हो सकता हैप्रेडाफ में स्कैला की आवश्यकता विधि क्यों स्ट्रिंग को तर्क के रूप में अनुमति देती है?

सबसे पहले सोचा कि विभिन्न मानकों के लिए दूसरी विधि के रूप में आवश्यकता विधि अधिभारित है। लेकिन यह नहीं है। विधि (स्काला 2.9.1) की आवश्यकता होती है के हस्ताक्षर है:

require(requirement: Boolean, message: ⇒ Any): Unit 

क्यों उपरोक्त विधि कॉल संभव है?

+2

परिभाषा के साथ क्या गलत है? '" foo "==" bar "' एक 'बूलियन' मान है और' स्ट्रिंग ''Any' (जैसा कि _any_ प्रकार करता है) के अनुरूप है। – Tharabas

+0

सवाल यह है कि क्यों एक स्ट्रिंग दूसरे तर्क के लिए वैध प्रकार है, जबकि हस्ताक्षर कहते हैं कि इसे एक समारोह 'संदेश होना चाहिए: => कोई भी' –

उत्तर

21

मैं इस प्रश्न को पूरी तरह से समझ नहीं पा रहा हूं, लेकिन यहां कुछ स्पष्टीकरण दिया गया है। require एक Predef में संस्करण अतिभारित है:

def require(requirement: Boolean) //... 
def require(requirement: Boolean, message: => Any) //... 

दूसरा एक थोड़ा message: => Any प्रकार की वजह से भ्रामक है। यह शायद आसान है, तो यह केवल था होगा:

def require(requirement: Boolean, message: Any) //... 

दूसरा पैरामीटर निश्चित रूप से एक संदेश है कि संदेश त्रुटि के लिए करता है, तो दावे को पूरा नहीं कर रहा है संलग्न किया जा के लिए लगता है है। आप कल्पना कर सकते messageString प्रकार का होना चाहिए, लेकिन Any साथ आप बस लिख सकते हैं:

require(x == 4, x) 

कौन सा एक त्रुटि संदेश में x (प्रकार Int की) के वास्तविक मूल्य जोड़ देगा अगर यह 4 के बराबर नहीं है। यही कारण है कि Any चुना गया था - मनमाना मूल्य की अनुमति के लिए।

लेकिन : => भाग के बारे में क्या? इसे नाम नाम से कॉल किया जाता है और मूल रूप से इसका अर्थ है: इस पैरामीटर का मूल्यांकन जब इसे तक पहुंचाया जाता है। निम्नलिखित स्निपेट कल्पना कीजिए:

require(list.isEmpty, list.size) 

इस मामले क्या आप वाकई list खाली है दिखाना चाहते हैं - और अगर ऐसा नहीं है, त्रुटि संदेश के वास्तविक list आकार जोड़ें। हालांकि सामान्य कॉल सम्मेलन के साथ list.size भाग से पहले मूल्यांकन किया जाना चाहिए विधि - जिसे अपमानजनक हो सकता है।नाम से कॉल करें सम्मेलन list.size केवल पहली बार इसका मूल्यांकन किया जाता है - जब त्रुटि संदेश कन्स्ट्रक्टर (यदि आवश्यक हो)।

+0

इससे बहुत मदद मिली, धन्यवाद। –

+0

@ टोमाज़ - मैं कॉल-बाय-नाम के विवरण से "आलसी" शब्द को हटाने के लिए उत्तर संपादित करने जा रहा हूं। मुझे लगता है कि यह भ्रामक है। आलसी (एक बार मूल्यांकन) और कॉल-बाय-नाम (प्रत्येक पहुंच का मूल्यांकन) के बीच एक अलग अंतर है। –

+0

@oxbow_lakes: कोई समस्या नहीं, मुझे समझ में आता है कि इसे 'आलसी' कीवर्ड से भ्रमित किया जा सकता है। धन्यवाद! –

3

विधि Predef में स्केल के डिफ़ॉल्ट पैरामीटर (2.8 में पेश किए गए) से पहले मौजूद था, इसलिए ओवरलोडिंग एकमात्र विकल्प था यदि आप किसी दिए गए पैरामीटर के लिए डिफ़ॉल्ट व्यवहार चाहते थे। संदेश द्वारा संकेत के रूप में, दूसरा तर्क कुछ भी है, जो तब फेंका IllegalArgumentException की (अपने toString विधि को फोन करके) message के रूप में प्रयोग किया जाता है, हो सकता है (अगर यह फेंक दिया जाता है - यानी यदि आवश्यकता विफल रहता है)।

ध्यान दें कि तर्क वास्तव में नाम द्वारा कॉल किया गया है; यानी, इसे => Any के रूप में घोषित किया गया है, जिसका अर्थ यह है कि केवल मूल्यांकन किया जाएगा यदि आवश्यकता विफल हो जाती है।

यह ऑब्जेक्ट सृजन के रूप में एक प्रदर्शन जुर्माना देता है, लेकिन यह उस मामले में उपयोगी हो सकता है जहां आपके संदेश का निर्माण महंगा है (शायद इसे डेटा संरचना के लिए कुछ ओ (एन) पहुंच की आवश्यकता है)।

-1

जवाब बहुत सरल है: आप

require(boolean: Boolean, message: => Any): Unit 

का दूसरा तर्क उम्मीद एक समारोहकिसी भी करने के लिए और पूछना एक String क्यों काम करता है हो सकता है, हालांकि यह एक समारोह नहीं है।

तोड़ इसे नीचे यह करने के लिए: एक निश्चित String लेकिन एक समारोह कि

  1. किसी भी तर्क नहीं ले करता है
  2. () कोष्ठक की आवश्यकता नहीं है
  3. ही पैदावार के नाम से जाना कुछ भी नहीं है परिणामस्वरूप प्रत्येक कॉल

वास्तव में निम्नलिखित दो कथन स्कैला में समतुल्य हैं:

def x: String = "ABC" // const value, even though 'def' implies a function 
val x: String = "ABC" 

तो तुम कह सकते हैं => Any एक String से संतुष्ट है।

+0

इससे बहुत मदद मिली, धन्यवाद। –

2

सवाल, क्यों एक स्ट्रिंग दूसरा तर्क कहते हैं, जबकि हस्ताक्षर यह एक समारोह message: => Any हो गया है के लिए मान्य प्रकार है।

हस्ताक्षर यह नहीं कहता है। हस्ताक्षर का कहना है कि दूसरा तर्क प्रकार Any है, और यह पैरामीटर नाम द्वारा पारित किया गया है।

"नाम से" लगाकर => प्रतीक जो नहीं मतलब समारोह करता है से निर्देशित होता है - एक समारोह हमेशा इंगित किया गया है इनपुट के रूप में =>परिणाम प्रकार पैरामीटर, Function0 जा रहा है () => type साथ।

"मूल्य से" और "नाम से" पैरामीटर देखें।

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

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