2011-07-11 16 views
24

我注意到,当我与期望其它功能参数的函数的工作,有时我能做到这一点:什么时候我必须将我的方法作为Scala中的部分应用函数处理?

someFunction(firstParam,anotherFunction) 

但其他时候,编译器是给我一个错误,告诉我,我应该写这样的功能,以便它把它当作一个部分应用功能:

someFunction(firstParam,anotherFunction _) 

例如,如果我有这样的:

object Whatever { 
    def meth1(params:Array[Int]) = ... 
    def meth2(params:Array[Int]) = ... 
} 

import Whatever._ 
val callbacks = Array(meth1 _,meth2 _) 

为什么我不能有这样的代码如下:

val callbacks = Array(meth1,meth2) 

在什么情况下,编译器告诉我补充_

回答

26

该规则其实很简单:只要编译器没有明确期待Function对象,就必须编写_

例如,在REPL:

scala> def f(i: Int) = i  
f: (i: Int)Int 

scala> val g = f 
<console>:6: error: missing arguments for method f in object $iw; 
follow this method with `_' if you want to treat it as a partially applied function 
     val g = f 
      ^

scala> val g: Int => Int = f 
g: (Int) => Int = <function1> 
4

除了让 - 菲利普·佩莱说,你可以使用部分应用功能,书写时委托类:

class ThirdPartyAPI{ 
    def f(a: Int, b: String, c: Int) = ... 
    // lots of other methods 
} 

// You want to hide all the unnecessary methods 
class APIWrapper(r: ThirdPartyAPI) { 
    // instead of writing this 
    def f(a: Int, b: String, c: Int) = r.f(a, b, c) 
    // you can write this 
    def f(a: Int, b: String, c: Int) = r.f _ 
    // or even this 
    def f = r.f _ 
} 

编辑添加def f = r.f _部分。

+4

请注意,这不是一个*部分功能*,这是一个*部分应用功能*。 –

+0

Thx,只是纠正它.. – agilesteel

+1

不应该(r:RichAPI)(r:ThnirdPartyAPI)? –

6

在斯卡拉一个方法不是的一个函数。编译器可以隐式地在一个函数中转换一个方法,但它需要知道哪一种。因此,无论您使用_它明确地转换或者你可以给一些迹象表明哪些功能要使用的类型:

object Whatever { 
    def meth1(params:Array[Int]): Int = ... 
    def meth2(params:Array[Int]): Int = ... 
} 

import Whatever._ 
val callbacks = Array[ Array[Int] => Int ](meth1, meth2) 

或:

val callbacks: Array[ Array[Int] => Int ] = Array(meth1, meth2)  
+0

另请参见[神话:方法和功能是相同的东西](http://stackoverflow.com/questions/3926047/debunking-scala-myths/4812176#4812176)。 –

相关问题