繁体   English   中英

Scala 功能1<t,u> 变成 Function1<object,object> 在 Java</object,object></t,u>

[英]Scala Function1<T,U> becomes Function1<Object,Object> in Java

我正在尝试使用 Java 中的 Deequ 库,但使用以下方法时遇到问题:

  def hasCompleteness(
      column: String,
      assertion: Double => Boolean,
      hint: Option[String] = None)
    : CheckWithLastConstraintFilterable = {
    addFilterableConstraint { filter => completenessConstraint(column, assertion, filter, hint) }
  }

特别是,对于断言,我需要传入一个Function1<Double, Boolean>

所以我使用下面的代码在Java中创建一个断言function:

public static Function1<Double, Boolean> atLeast(double thresholdPercentage) {
  return new scala.compat.java8.functionConverterImpls.FromJavaFunction<>((Double actualPercentage) -> actualPercentage >= thresholdPercentage);
}

很简单,对吧?

只是,我的 Java Class 现在无法编译,因为hasCompleteness方法的签名,从 Java来看,断言参数是一个Function1<Object, Object> 因此,我看到以下错误:

Required type: Function1<Object, Object>
Provided: Function1<Double, Boolean>

如果我更改我的atLeast方法以返回未参数化的Function1问题就会消失,但这感觉就像一个丑陋的杂物。

使用 Java 中的这种方法时,我是否注定会丢失类型参数? 还是我的 IntelliJ / Gradle 设置可能有问题导致这种奇怪的行为?

That seems how Scala compiler translates "primitive" Scala types (remember, Double here is scala.Double and not java.lang.Double ). 例如 Scala 声明

  var d: Double => Boolean;
  var s: String => String;

产生(如javap所示):

  public abstract scala.Function1<java.lang.Object, java.lang.Object> d();
  public abstract scala.Function1<java.lang.String, java.lang.String> s();

请注意如何DoubleBoolean都转换为Object ,但String被保留

彼得兹详细描述了幕后发生的事情。

Sounds like what you need is an explicit conversion from the primitive double Java predicate ( java.util.function.DoublePredicate ) to the scala.Double Scala predicate ( Double => Boolean ).

Scala 实际上提供了一种称为FromJavaDoublePredicate的转换。 该代码不再需要显式Double强制转换:

  /* some scala file */
  def hasCompleteness(
      x: Double,
      f: Double => Boolean
  ): Unit = println(f(x))

  /* some java file */
  public static FromJavaDoublePredicate atLeast(double thresholdPercentage) {
      return new scala.compat.java8.functionConverterImpls.FromJavaDoublePredicate(
        actualPercentage -> actualPercentage >= thresholdPercentage);
  }

  FromJavaDoublePredicate f = atLeast(3.0);
  Test.hasCompleteness(5, f);  // true

PS。 从我所见,您选择了scala-java8-compat ,所以我假设您使用的是 Scala 的早期版本。 他们的维护者 state:

如果您仅使用 Scala 2.13 或更新版本,请不要使用此库! 改用scala.jdk下的类; 它们在 2.13 中被添加到标准库中。

因此,对于 Scala 2.13.x,我建议在FunctionWrappers object 中使用FromJavaDoublePredicate案例 class 。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM