簡體   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