Pergunta

Para interoperabilidade, preciso passar um Scala PartialFunction do código Java.Para Function (Function1 e assim por diante), existe AbstractFunction que posso subclassificar com um tipo anônimo, mas qual seria a maneira mais fácil de fazer o mesmo para PartialFunction?

Nesse caso, eu ficaria feliz se ela fosse uma função "completa" em Java, aparecendo definida para todos os valores, mas digitada como PartialFunction.

Foi útil?

Solução

Se você puder usar o Twitter Util Library, ele tem uma aula especificamente para esta: http://twitter.github.com/util/util-core/target/site/doc/main/api/com/twitter/util/function.html Qual é basicamente a mesma solução que a funde abstrataPartial.

Outras dicas

O que eu faria aqui é fornecer uma interface em Java, em alguma biblioteca comum (que não reconhece scala):

//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);
}

Então, em escala (ou seja,uma biblioteca scala dependente da biblioteca Java acima), converta uma implementação desta em um 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
    }
  }
}

Então seu código Java pode fazer isso:

//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) { /* */ }
}

Se você não gosta do MyPartialFunctions$.MODULE$ sintaxe, é possível na biblioteca scala, a Classe Java que esconde isso de você:

//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);
    }
}

Então seu call-site fica assim:

//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) { /* */ }
}

Isso envolve, aham, alguns níveis de indireção!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top