2010-05-05 14 views
28
def foo(x:Int, f:Unit=>Int) = println(f()) 

foo(2, {Unit => 3+4} 

//case1 
def loop:Int = 7 
foo(2, loop) //does not compile 

changing loop to 
//case 2 
def loop():Int = 7 
foo(2, loop) // does not compile 

changing loop to 
//case 3 
def loop(x:Unit): Int = 7 //changing according to Don's Comments 
foo(2,loop) // compiles and works fine 

केस 1 और केस 2 भी काम नहीं करना चाहिए? वे क्यों काम नहीं कर रहे हैं?तर्क के बिना कार्य, स्केल

को परिभाषित करने foo

def foo(x:Int, y:()=>Int) 

फिर 2 काम करता है मामला नहीं बल्कि मामले के रूप में 1.

Arent वे सभी कार्य किसी भी तरह से परिभाषित करने के लिए काम करना चाहिए।

// मुझे लगता है कि() => int में foo एक खराब शैली है, y: => Int काम नहीं करता है, टिप्पणियां ??

+2

def विधियों को परिभाषित करता है (जो प्रथम श्रेणी नहीं हैं), फ़ंक्शन नहीं (जो * प्रथम श्रेणी हैं)। आंशिक अनुप्रयोग जब आपको उनकी आवश्यकता होती है तो कार्य करने के तरीकों को ले जाती है। –

+1

क्या आप विस्तृत कर सकते हैं .. मुझे यह नहीं मिला। क्या आपका मतलब था कि डीफ़ को पास नहीं किया जा सकता है। यानी उपरोक्त "लूप" अन्य कार्यों में पारित नहीं किया जा सकता है? – scout

+2

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

उत्तर

74

एक वस्तु है स्काला निम्नलिखित बातें अलग बीच:

  • कार्य/कोई पैरामीटर सूचियों ("द्वारा साथ तरीकों -name पैरामीटर "अगर एक समारोह)
  • एक खाली पैरामीटर सूची के साथ कार्य एक प्रकार यूनिट के पैरामीटर के साथ
  • कार्य इनमें से

कोई नहीं, बराबर हैं, हालांकि एक सुविधा के रूप स्काला आप की अनुमति देता है खाली पैरामीटर सूचियों को दूर करने के लिए। तो (संयोग से, दो खाली पैरामीटर सूचियों भी नहीं ही हैं।)

, भले ही Unit() लिखा है, यह है नहीं समारोह तर्क के रूप में एक ही कोष्ठक एक समारोह या विधि के लिए ()। इसके बजाय, () को Tuple0 के रूप में सोचें।

तो, अगर आप कहते हैं कि f: Unit => Int, तुम क्या मतलब है "च एक पैरामीटर लेता है, लेकिन यह एक सच में बोरिंग पैरामीटर है, क्योंकि यह Unit है, जो हमेशा एक ही उबाऊ Tuple0 मूल्य () होना चाहिए" है। आप जो लिख रहे हैं वह f: (Unit) => Int के लिए वास्तव में छोटा है।

यदि आप f:() => Int कहते हैं, तो आप का मतलब है कि "एफ कोई पैरामीटर नहीं लेता है और Int उत्पन्न करता है"।

यदि आप f: => Int कहते हैं, तो आप का मतलब है कि "जो भी कथन निष्पादन में देरी करता है, उसे Int मान उत्पन्न करता है जब तक हम इस कोड में इसका उपयोग नहीं करते हैं (और हर बार फिर से मूल्यांकन करते हैं)"। कार्यात्मक रूप से, यह मूल रूप से f:() => Int के समान होता है (और आंतरिक रूप से उसी Function0 वर्ग में परिवर्तित हो जाता है), लेकिन इसका एक अलग उपयोग होता है, संभावित रूप से बंद होने के अधिक कॉम्पैक्ट रूप की अनुमति देने के लिए (आप हमेशा => को कॉलिंग कोड में छोड़ देते हैं)।

+0

तो यदि मेरे पास फ़ंक्शन डिफ लूप() है = 7 डीफ़ लूप (x: यूनिट) = 7 में, यदि मैं इसे ऊपर किसी अन्य फ़ंक्शन पर पास करना चाहता हूं, तो यह वास्तव में इकाई को सम्मिलित करने के लिए मुझे कोई समझ नहीं आता है। – scout

+2

@ स्काउट: उस मामले में एक अनावश्यक 'यूनिट' जोड़ने का कोई कारण नहीं है। यह अमूर्तता के लिए उपयोगी है। मान लें कि आपके पास एक रचना समारोह है: 'def comp [ए, बी, सी] (एफ: ए => बी, जी: बी => सी, ए: ए) = जी (एफ (ए))' और आप पास करने का प्रयास करते हैं यह एक 'एफ' है जो एक मूल्य वापस नहीं करता है। अब तुम क्या करते हो? खैर, यह पता चला है कि स्कैला हमेशा _does_ कुछ वापस लौटाता है - कम से कम '()' (प्रकार 'यूनिट' का एकमात्र संभावित मूल्य)। तो अब आप एक 'जी' लिख सकते हैं जो 'यूनिट' प्रकार का इनपुट लेता है और ऊपर सामान्य संरचना फ़ंक्शन का उपयोग करता है। लेकिन ज्यादातर स्थितियों के लिए, बस 'def f() = ...' या 'def f = ...' का उपयोग करें। स्पष्टीकरण के लिए –

+1

धन्यवाद। मैं यह पता लगाने की कोशिश कर रहा था कि आलसी विकास कैसे करें। ध्यान दें कि 'f: => int' में ':' और '=' के बीच की जगह महत्वपूर्ण है। – Jus12

14

() => इंट Function0 [इंट] है, जबकि यूनिट => इंट Function1 [यूनिट, जे] है

scala> val function0:() => Int =() => 5 
function0:() => Int = <function0> 

scala> val function1: Unit => Int = u => 5 
function1: (Unit) => Int = <function1> 

scala> function0() 
res0: Int = 5 

scala> function1("anything") 
res1: Int = 5 

scala> function1(100) 
res2: Int = 5 

scala> 

भी ध्यान रखें कि() यूनिट

की
scala> function1(()) 
res11: Int = 5 

scala> function1() 
res12: Int = 5 

scala> function1() 
res13: Int = 5 

scala> val unit =() 
unit: Unit =() 


scala> function1(unit) 
res15: Int = 5 

scala> function1 apply unit 
res16: Int = 5 

scala> 
+0

स्कैला> वैल फ़ंक्शन 1: यूनिट => इंट = यूनिट => 5 ध्यान दें कि इस पंक्ति में, अंतिम "यूनिट" एक प्रकार पहचानकर्ता नहीं है, लेकिन पैरामीटर के लिए सिर्फ एक नाम है (आप इसे "x" में बदल सकते हैं उदाहरण के लिए)। –

+0

@ डिमिटिस एंड्रयू: हाँ, आप सही हैं। – Eastsun

+0

मुझे मिलता है कि क्यों 'function1 (()) 'और' function1()' काम करता है, लेकिन मुझे समझ में नहीं आता कि क्यों 'function1() 'काम करता है। मैं उम्मीद करता हूं कि यह स्कैला में सामान्य विधि आमंत्रण नियमों का पालन करे, यानी, आपको फ़ंक्शन नाम के बाद स्थान या पैरामीटर पैरों के बीच इकाई मान की आवश्यकता होगी ... – ThaDon

2

मामले 1 में और इसके बाद के संस्करण 2, पाशबजाय पाश के रिटर्न मान ही foo को दूसरा तर्क के लिए जाँच की और विफल रहता है प्रकार है: इंट = यूनिट => इंट

लूप में परिवर्तन एक टाइपो है।

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