12 Stimmen

Was ist der einfachste Weg, eine Scala PartialFunction in Java zu implementieren?

Für Interoperabilität muss ich eine Scala PartialFunction von Java-Code aus übergeben. Für Function (Function1 und so weiter) gibt es AbstractFunction, von dem ich mit einem anonymen Typ ableiten kann, aber wie könnte ich das Gleiche für PartialFunction am einfachsten tun?

In diesem Fall würde ich mich freuen, wenn es in Java als "vollständige" Funktion erscheinen würde, die für alle Werte definiert ist, aber als PartialFunction getypt ist.

9voto

oxbow_lakes Punkte 131223

Was ich hier tun würde, ist eine Schnittstelle in Java in einer allgemeinen Bibliothek bereitzustellen (die nicht scala-bewusst ist):

//this is Java - in the Java lib
abstract class PartialTransformer {
    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);
}

Dann, in Scala (d.h. eine Scala-Bibliothek, die von der oben genannten Java-Bibliothek abhängt), wandeln Sie eine Implementierung davon in eine PartialFunction um:

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

Dann kann Ihr Java-Code das folgendes tun:

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

Wenn Ihnen die Syntax MyPartialFunctions$.MODULE$ nicht gefällt, ist es möglich in der Scala-Bibliothek, eine Java-Klasse zu haben, die dies von Ihnen versteckt:

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

Dann sieht Ihr Aufruf so aus:

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

Dies beinhaltet, ähm, ein paar Ebenen von Indirektion!

6voto

Viktor Klang Punkte 26185

6voto

Alexey Romanov Punkte 160158

Wenn Sie die Twitter Util-Bibliothek verwenden können, verfügt sie über eine Klasse, die speziell für dieses Problem entwickelt wurde: http://twitter.github.com/util/util-core/target/site/doc/main/api/com/twitter/util/Function.html, was im Grunde die gleiche Lösung wie AbstractPartialFunction ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X