2011-11-18 45 views
7

Tengo una clase de Java que tiene acceso a un contexto de transacción que me gustaría usar desde Scala. Así que pensé que me gustaría escribir un método Java que toma una función Scala y la llama dentro de la transacción -¿Hay una función lambda en Scala?

class Context { 
    @Transactional public void runInTx(Function0<scala.Unit> f) { 
     f.apply(); 
    } 

Hasta aquí todo bien. Me gustaría ser capaz de pasar un cierre Scala a ella

def deleteItems(ids: Set[Long]) = { 
    context.runInTx { ids foreach { dao.delete(_) } } 
} 

pero no puedo porque runInTx no está realmente llamo por su nombre, y ids foreach { dao.delete(_) } no es en realidad un Function0.

Ahora puedo resolver este problema con un pequeño golpe seco

def deleteItems(ids: Set[Long]) = { 
    def localApply(f: => Unit) = context.applyInTx(f _) 
    localApply { ids foreach { dao.delete(_) } } 
} 

pero me parece que necesito una función lambda para producir un anónimo Function0 de un bloque de código.

¿Existe tal cosa en la API, o cómo podría hacerlo?

Respuesta

11

Puede decirle al compilador que interprete el bloque como una función en lugar de una instrucción que se invocará inmediatamente al agregar los parámetros (en este caso falta).

Así que en este caso:

def deleteItems(ids: Set[Long]) = { 
    context.runInTx {() => ids foreach { dao.delete(_) } } 
} 

() => ids foreach { dao.delete(_) } es la forma completa de la función literal. El compilador permite omitir la lista de parámetros en lugares donde se puede inferir que se requiere una función: esto es cierto para llamar por nombre, pero no parece ser cierto al pasar a un método tomando Function

Cuestiones relacionadas