2012-03-03 10 views
7

मैं निम्नलिखित दो कार्यों को परिभाषित कर सकते हैं:आंशिक फ़ंक्शन 2 फ़ंक्शंस पर क्यों लागू होता है जो एक ही चीज को दो अलग-अलग तरीकों से परिभाषित करता है, एक अलग परिणाम देता है?

def add(a: Int, b: Int, c: Int) = a + b + c 

इस

add: (a: Int, b: Int, c: Int)Int 

और

val add2 = (a: Int, b: Int, c: Int) => a + b + c 

इस

add2: (Int, Int, Int) => Int = <function3> 

दोनों में जो परिणाम में परिणाम इन के कार्यों कि बिल्कुल वही चीज़ करते लेकिन एक अलग तरीके से परिभाषित कर रहे हैं, अगर मैं आगे जाना है और इस प्रकार एक आंशिक रूप से लागू किया समारोह को परिभाषित क्या मुझे समझ नहीं आता है:

def a = add _ 

यह

a: (Int, Int, Int) => Int = <function3> 
में जो परिणाम

की उम्मीद के रूप में, एक समारोह है कि 3 पैरामीटर लेता है और एक इंट दिखाए, लेकिन यह

में परिणाम अगर मैं

def a2 = add2 _ 

करना

a2:() => (Int, Int, Int) => Int = <function0> 

जो एक ऐसा प्रतीत होता है जो कोई पैरामीटर नहीं लेता है और एक फ़ंक्शन देता है जो 3 इंट पैरामीटर लेता है और एक इंट देता है। ऐसा क्यों होता है? क्या कोई बता सकता है कि क्या हो रहा है?

धन्यवाद

+0

[कार्यों के दो तरीके की घोषणा के संभावित डुप्लिकेट। भेद क्या है?] (Http://stackoverflow.com/questions/2720486/declaring-functions-two-ways-what-is-the-distinction) –

+0

वह डुप्लिकेट तीसरा संबंधित लिंक था। वास्तव में, पहले पूछे जाने वाले प्रश्न को देखने का प्रयास करें - इस से कई बार पूछा गया है। जबकि मुझे लगता है कि लिंक निकटतम डुप्लिकेट है, मैं व्यक्तिगत रूप से [इस उत्तर] की सिफारिश करता हूं (http://stackoverflow.com/questions/2529184/difference-between-method-and-function-in-scala/2530007#2530007) मेरा विषय के निचले हिस्से तक पहुंचने के लिए। –

+0

ओह, वैसे, शायद आप स्पष्ट होंगे अगर आप 'val add2' के बजाय 'def add2' लिखते हैं। –

उत्तर

9

यह स्काला वास्तव में (उपयोगकर्ता के सुलभ) खेतों नहीं होने, लेकिन इसके बजाय सब कुछ के लिए accessors (getters) होने का एक अजीब पक्ष प्रभाव है। का निरीक्षण करें:

scala> val i = 1 
i: Int = 1 

scala> i _ 
res0:() => Int = <function0> 

कारण यह है कि i वास्तव में एक अंतर्निहित (छिपा हुआ, दुर्गम) क्षेत्र के लिए एक्सेसर (def i: Int) है। चूंकि यह सिर्फ एक विधि है, _ इसे एक फ़ंक्शन में परिवर्तित कर देगा। एक्सेसर कोई तर्क नहीं लेता है, यही कारण है कि आपके पास ऐसा फ़ंक्शन है जो कोई पैरामीटर नहीं लेता है।

+0

+1 लेकिन मुझे नहीं लगता कि यह प्रभाव _strange_ है – Odomontois

1

प्रभाव Rex Kerr's answer में स्पष्ट रूप से वर्णित है लेकिन आपको ध्यान रखना चाहिए कि add2 मान पहले ही आंशिक रूप से लागू फ़ंक्शन का प्रतिनिधित्व करता है, उदाहरण के लिए प्रतिनिधि। प्रदर्शन के लिए आप add1 _ अभिव्यक्ति के प्रकार और add2 मान की तुलना कर सकते हैं।

scala> def getManifest[T](x:T)(implicit m:scala.reflect.Manifest[T]) = m 
getManifest: [T](x: T)(implicit m: scala.reflect.Manifest[T])scala.reflect.Manifest[T] 

scala> getManifest(add1 _) == getManifest(add2) 
res14: Boolean = true 
2

स्कैला में दोनों कार्य और विधियां हैं, वे काफी समान नहीं हैं।

def add(a: Int, b: Int, c: Int) = a + b + c 

जिसने एक विधि परिभाषित की है (एक समारोह नहीं !!)।

val add2 = (a: Int, b: Int, c: Int) => a + b + c 

जो एडी 2 को एक फ़ंक्शन मान निर्दिष्ट करता है (विधि नहीं !!)।

एक विधि, अंतिम मूल्य नहीं हो सकता है, जबकि एक समारोह कर सकते हैं:

scala> add 
<console>:9: error: missing arguments for method add; 
follow this method with `_' if you want to treat it as a partially applied function 
       add 
      ^

scala> add2 
res1: (Int, Int, Int) => Int = <function3> 

scala> val a = add 
<console>:8: error: missing arguments for method add; 
follow this method with `_' if you want to treat it as a partially applied function 
     val a = add 
      ^

scala> val a2 = add2 
a2: (Int, Int, Int) => Int = <function3> 

विधि नाम के बाद एक अंडरस्कोर लेखन स्पष्ट रूप से एक विधि एक समारोह में तब्दील कर सकते हैं:

scala> add _ 
res2: (Int, Int, Int) => Int = <function3> 

लेकिन यदि आप किसी मान के बाद अंडरस्कोर लिखते हैं, तो यह उस फ़ंक्शन में परिवर्तित हो जाएगा जो इसके प्रकार के रिटर्न प्रकार के साथ कोई तर्क नहीं लेता है:

scala> val s = "" 
s: String = "" 

scala> val i = 1 
i: Int = 1 

scala> s _ 
res3:() => String = <function0> 

scala> i _ 
res4:() => Int = <function0> 

तो अगर मूल्य अपने आप में एक समारोह, एक अंडरस्कोर लेखन के बाद यह एक नया समारोह जो समारोह की वापसी प्रकार के साथ कोई तर्क ले मिल जाएगा है:

scala> add2 _ 
res5:() => (Int, Int, Int) => Int = <function0> 
संबंधित मुद्दे