27

我注意到,当我使用期望其他函数作为参数的函数时,有时我可以这样做:

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)

在什么情况下编译器会告诉我添加_

4

3 回答 3

28

规则实际上很简单:_只要编译器没有明确地期望一个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>
于 2011-07-11T13:50:21.820 回答
6

In Scala a method is not a function. The compiler can convert a method implicitly in a function, but it need to know which kind. So either you use the _ to convert it explicitly or you can give some indications about which function type to use:

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

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

or:

val callbacks: Array[ Array[Int] => Int ] = Array( meth1, meth2 )    
于 2011-07-11T15:00:40.807 回答
4

除了 Jean-Philippe Pellet 所说的,您可以在编写委托类时使用部分应用函数:

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 _
}

EDIT added the def f = r.f _ part.

于 2011-07-11T14:15:55.443 回答