2011-11-24 16 views
6

स्कैला में एक फ़ंक्शन एक ऑब्जेक्ट है जो FunctionN लक्षणों में से एक को लागू करता है। उदाहरण के लिए:फ़ंक्शन एन विशेषता क्या है जो एक उप-पैरामीटर लेते हुए फ़ंक्शन का प्रतिनिधित्व करती है?

scala> def f(x: Int) = x * x 
f: (x: Int)Int 

scala> val ff = f _ 
ff: Int => Int = <function1> 

scala> val fff: Function1[Int, Int] = f _ 
fff: Int => Int = <function1> 

अभी तक, बहुत अच्छा है। लेकिन क्या होगा यदि हमारे पास कोई ऐसा कार्य है जो उप-नाम पैरामीटर लेता है? यह निश्चित रूप से अभी भी FunctionN लक्षण में से एक को लागू करता है:

scala> def g(x: => Int) = x * x 
g: (x: => Int)Int 

scala> val gg = g _ 
gg: => Int => Int = <function1> 

scala> gg.isInstanceOf[Function1[_, _]] 
res0: Boolean = true 

लेकिन किस प्रकार यह है, वास्तव में? यह Function1[Int, Int] नहीं है:

scala> val ggg: Function1[Int, Int] = g _ 
<console>:8: error: type mismatch; 
found : => Int => Int 
required: Int => Int 
     val ggg: Function1[Int, Int] = g _ 
            ^

न ही यह Function1[Function0[Int], Int] है:

scala> val ggg: Function1[=> Int, Int] = g _ 
<console>:1: error: identifier expected but '=>' found. 
     val ggg: Function1[=> Int, Int] = g _ 
         ^

तो यह क्या है:

scala> val ggg: Function1[Function0[Int], Int] = g _ 
<console>:8: error: type mismatch; 
found : => Int => Int 
required:() => Int => Int 
     val ggg: Function1[Function0[Int], Int] = g _ 
               ^

और Function1[=> Int, Int] संकलन करने में विफल रहता है?

उत्तर

4

उप-नाम बहुत उपयोगी है लेकिन टाइप सिस्ट के बाहर असुरक्षित है एम

स्कैला द्वारा नाम पैरामीटर एक सिंटेक्टिक चीनी हैं जो आलसी मूल्यांकन की आवश्यकता होने पर कोड को और अधिक पठनीय बनाने के लिए होते हैं। इसके बिना हमें आलसी होने के लिए आवश्यक सब कुछ के सामने "() =>" डालना होगा। उस ने कहा, जबकि यह रनटाइम पर केवल एक function0 है, यह टाइपिंग सिस्टम स्तर पर समस्याग्रस्त होगा यदि आप उप-नाम प्रकार के पैरामीटर के अलावा कुछ भी परिभाषित कर सकते हैं। यह भी याद रखें कि फंक्शन एन लक्षण ज्यादातर कार्यान्वयन और जावा इंटरऑपरेबिलिटी के लिए हैं क्योंकि जावा और जेवीएम में फ़ंक्शन प्रकार जैसी कोई चीज़ नहीं है।

होने के नाते स्पष्ट

आप अपने निम्नलिखित टाइपिंग प्रतिबंधात्मक स्थितियों के लिए अनुमति देगा

def g(x: => Int) = x * x 
val ggg: (=> Int) => Int = g _ 

अधिक जटिल टाइपिंग

The-नाम से स्पष्ट होने की जरूरत है, तो टाइपिंग केवल फ़ंक्शन प्रकार घोषणाओं के पैरामीटर भाग के अंदर उपयोग की जा सकती है। फ़ंक्शन प्रकार स्वयं को अन्य पैरामीरिज्ड प्रकारों के अंदर उपयोग किया जा सकता है।

var funks: List[(=> Int) => Int] = Nil 
funks ::= ggg 
funks foreach { _ { println("hi"); 5 } } 
1

रेक्स केर का जवाब this question आपको एक संकेत देता है: उप-नाम तर्क अंततः Function0 में परिवर्तित हो गया है, लेकिन शायद विशेष रूप से संकलन-समय पर इसका इलाज किया जाता है।

आप इस की पुष्टि कर सकते हैं:

scala> gg(sys.error("me")) 
java.lang.RuntimeException: me 
    at scala.sys.package$.error(package.scala:27) 
    at $anonfun$1.apply(<console>:10) 
    at $anonfun$1.apply(<console>:10) 
    at scala.Function0$class.apply$mcI$sp(Function0.scala:34) 
    at scala.runtime.AbstractFunction0.apply$mcI$sp 
    ... 

संपादित

मेरी पहली टिप्पणी पर विस्तार करने के लिए, यह भी इंगित करता है कि आप एक प्रकार एक उप-नाम पैरामीटर के लिए नहीं दे सकता:

def test[A: Manifest](fun: Function1[A, Int]): Unit = 
    println("Found " + implicitly[Manifest[A]]) 

scala> test(gg) 
<console>:11: error: No Manifest available for => Int. 
       test(gg) 
       ^
+0

निश्चित - मुझे कोई संदेह नहीं है कि हुड के नीचे क्या हो रहा है।लेकिन अगर मैं इसे अनुमानित करने की अनुमति देने के बजाय फ़ंक्शन के प्रकार को निर्दिष्ट करना चाहता हूं, तो यह वास्तव में क्या है? निश्चित रूप से यह मामला नहीं हो सकता है कि मैं कुछ ऐसा बना सकता हूं जहां मैं अपना प्रकार लिख नहीं सकता? यह कर सकते हैं?! –

+0

मुझे यकीन नहीं है कि आप ऐसा कर सकते हैं। यही कहना है कि वास्तव में एक उप-नाम तर्क के अनुरूप एक 'प्रकार' है। जैसे 'gg.getClass.getMethods.find (_। getName ==" लागू करें ") प्राप्त करें। 'फंक्शन 0' का एक तर्क प्रकार भी प्राप्त करें। लेकिन * कंपाइलर * के लिए, यह रूपांतरण अभी तक नहीं हुआ है, इस प्रकार यह आपको बताता है कि 'फंक्शन 0' आवश्यक प्रकार नहीं है (आपकी पिछली बार कोशिश करें)। –

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