【问题标题】:What is the easiest way to implement a Scala PartialFunction in Java?在 Java 中实现 Scala PartialFunction 的最简单方法是什么?
【发布时间】:2012-05-18 09:48:48
【问题描述】:

为了互操作性,我需要从 Java 代码中传递一个 Scala PartialFunction。对于 Function(Function1 等),有一个 AbstractFunction,我可以使用匿名类型对其进行子类化,但是对于 PartialFunction,最简单的方法是什么?

在这种情况下,我很乐意让它成为 Java 中的“完整”函数,为所有值定义,但类型为 PartialFunction。

【问题讨论】:

    标签: java scala partialfunction


    【解决方案1】:

    我在这里要做的是在一些通用库(不支持 scala)中提供一个 Java 接口:

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

    然后,在 scala 中(即依赖于上述 Java 库的 scala 库),将其实现转换为 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
        }
      }
    }
    

    那么你的 Java 代码可以这样做:

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

    如果您不喜欢MyPartialFunctions$.MODULE$ 语法,可以在 scala 库中,一个 Java 类 对您隐藏:

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

    那么您的呼叫站点如下所示:

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

    这涉及到,咳咳,一些间接层次!

    【讨论】:

    • 我考虑在 Scala 中创建一些包装器/工厂。但是,对于这个项目,我自己无法在 Scala 中生成任何代码。
    【解决方案2】:

    如果你可以使用 Twitter Util 库,它有一个专门用于此的类:http://twitter.github.com/util/util-core/target/site/doc/main/api/com/twitter/util/Function.html,它与 AbstractPartialFunction 的解决方案基本相同。

    【讨论】:

      【解决方案3】:

      【讨论】:

      • 谢谢。知道 Akka for Scala 2.10 何时发布?
      • Scala 2.10 发布时的某个时间。
      • Twitter claims AbstractPartialFunction 并不适用于 Java 互操作,应该使用它们的 com.twitter.util.Function 代替。但推理却很模糊......
      猜你喜欢
      • 2011-03-21
      • 2023-03-20
      • 2018-02-09
      • 1970-01-01
      • 2013-08-07
      • 2018-12-19
      • 1970-01-01
      • 2010-11-23
      相关资源
      最近更新 更多