2012-05-18 8 views
11

Para la interoperabilidad, necesito pasar un Scala PartialFunction del código de Java. Para Function (Function1 y así sucesivamente), hay AbstractFunction que puedo crear una subclase con un tipo anónimo, pero ¿cuál sería la forma más fácil de hacer lo mismo para PartialFunction?¿Cuál es la forma más fácil de implementar Scala PartialFunction en Java?

En este caso, me gustaría que fuera una función "completa" en Java, apareciendo definida para todos los valores, pero escrita como una función parcial.

Respuesta

9

Lo que quiero hacer aquí es proporcionar una interfaz en Java, de alguna biblioteca común (que no es-scala conscientes):

//this is Java - in the Java lib 
abstract class PartialTransformer<I, O> { 
    abstract public boolean isDefinedAt(I i); 
    public O transform(I i) { 
     if (isDefinedAt(i)) { 
      return transform0(i); 
     } 
     return null; 
    } 
    abstract protected O transform0(I i); 
} 

Entonces, depende en Scala (es decir, una biblioteca Scala en el por encima de la biblioteca de Java), convertir una aplicación de esta a un PartialFunction:

//this is scala - in the scala lib 
object MyPartialFunctions { 
    def fromPartialTransformer[I, O](t: PartialTransformer[I, O]) = new PartialFunction[I, O] { 
    def isDefinedAt(i: I) = t isDefinedAt i 
    def apply(i: I) = { 
     val r = t transform i 
     if (r eq null) throw new MatchError 
     else r 
    } 
    } 
} 

a continuación, el código Java puede hacer esto:

//This is Java - in your client code 
MyPartialFunctions$.MODULE$.fromPartialTransformer(new PartialTransformer<Integer, String>() { 
    @Override public boolean isDefinedAt(Integer i) { /* */ } 
    @Override protected String transform0(Integer i) { /* */ } 
} 

Si no te gusta la sintaxis MyPartialFunctions$.MODULE$, es posible en la biblioteca Scala, una clase Java que esconde esto de ti:

//This is Java - in the scala-lib 
public class ScalaUtils { 
    public <I, O> scala.PartialFunction<I, O> toPartialFunction(PartialTransformer<I, O> t) { 
     MyPartialFunctions$.MODULE$.fromPartialTransformer(t); 
    } 
} 

Entonces su llamada in situ se ve así:

//This is Java - in your client code 
ScalaUtils.toPartialFunction(new PartialTransformer<Integer, String>() { 
    @Override public boolean isDefinedAt(Integer i) { /* */ } 
    @Override protected String transform0(Integer i) { /* */ } 
} 

Esto implica, ejem, algunos niveles de indirección.

+0

He considerado crear una envoltura/fábrica en Scala. Sin embargo, para este proyecto no puedo producir ningún código en Scala. – SoftMemes

Cuestiones relacionadas