2011-07-11 13 views
24

he notado que cuando estoy trabajando con funciones que esperan otras funciones como parámetros, que a veces puede hacer esto:¿Cuándo debo tratar mis métodos como funciones parcialmente aplicadas en Scala?

someFunction(firstParam,anotherFunction) 

Pero otras veces, el compilador me da un error, me decía que yo debería escribir una función como esta, a fin de que tratarlo como una función aplicada parcialmente:

someFunction(firstParam,anotherFunction _) 

por ejemplo, si tengo esto:

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

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

Por qué no puedo tener el código como el siguiente:

val callbacks = Array(meth1,meth2) 

¿En qué circunstancias el compilador dime para añadir _?

Respuesta

26

La regla es realmente simple: tiene que escribir el _ siempre que el compilador no espere explícitamente un objeto Function.

Ejemplo en el 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

Además de las funciones de lo que dijo Jean-Philippe de pellets, se puede utilizar parcialmente aplicadas, al escribir clases de delegado:

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 añade el def f = r.f _ parte.

+4

Tenga en cuenta que no es un * función parcial *, que es una * función parcialmente aplicada *. –

+0

Thx, acaba de corregirlo .. – agilesteel

+1

No debería (r: RichAPI) ser (r: ThirdPartyAPI)? –

6

En Scala, un método no es una función. El compilador puede convertir un método implícitamente en una función, pero necesita saber qué tipo. Por ello debe usar el _ para convertirlo explícitamente o se puede dar algunas indicaciones acerca de qué tipo de función Modo de empleo:

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

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

o:

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

Vea también [Mito: los métodos y las funciones son la misma cosa] (http://stackoverflow.com/questions/3926047/debunking-scala-myths/4812176#4812176). –

Cuestiones relacionadas