What is the easiest way to implement a Scala PartialFunction in Java?

泄露秘密 提交于 2019-12-04 18:46:51

问题


For interoperability, I need to pass a Scala PartialFunction from Java code. For Function (Function1 and so on), there is AbstractFunction that I can subclass with an anonymous type, but what would be the easiest way of doing the same for PartialFunction?

In this case, I would be happy to have it being a "complete" function in Java, appearing defined for all values, but typed as a PartialFunction.


回答1:


If you can use Twitter Util library, it has a class specifically for this: http://twitter.github.com/util/util-core/target/site/doc/main/api/com/twitter/util/Function.html which is basically the same solution as AbstractPartialFunction.




回答2:


What I would do here is provide an interface in Java, in some common library (which is not scala-aware):

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

Then, in scala (i.e. a scala library dependent on the above Java library), convert an implementation of this to a 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
    }
  }
}

Then your Java code can do this:

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

If you don't like the MyPartialFunctions$.MODULE$ syntax, it's possible in the scala library, a Java class which hides this from you:

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

Then your call-site looks like this:

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

This involves, ahem, a few levels of indirection!




回答3:


As a complement to Chris' answer, in Scala 2.10 you can use this: http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/runtime/AbstractPartialFunction.html



来源:https://stackoverflow.com/questions/10650338/what-is-the-easiest-way-to-implement-a-scala-partialfunction-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!