scala - 使用参数默认值键入删除

标签 scala type-erasure default-parameters

以下不编译:

package play

object Stats2 {
  def variance(data: Seq[Double], dof: Int = 0): Double = {
    println("variance Double direct"); 1.0
  }
  def variance[T](data:Seq[T], dof: Int = 0)(implicit ex: T => Double): Double = {
    println("variance Double extracted"); 1.0
  }
} 

编译器说:
$ scalac erasure2.scala 
erasure2.scala:7: error: double definition:
method variance$default$2:[T]=> Int and
method variance$default$2:=> Int at line 4
have same type after erasure: ()Int
  def variance[T](data:Seq[T], dof: Int = 0)(implicit ex: T => Double): Double = {
                               ^
one error found

自由度:Int = 0 改为 自由度:国际 ,该示例编译并按预期工作。

默认参数值的存在与否会改变代码是否有效,这看起来很丑陋。

为什么这真的有意义的解释是什么?

最佳答案

问题是当你使用默认参数时,它的名字和方法名被用来生成一个静态属性,这样:[methodName]$default$[argumentPosition] ,在您的情况下,它将是 variance$default$2 ,所以如果两者都有默认参数,编译器将尝试生成 2 个同名的静态属性。

如果使用了方法中其他参数的类型,则可以避免这种情况。您可以 submit a SIP建议在编译器中更改此行为。

您可以在此阅读更多相关信息 post

如果您想自己检查,请尝试使用每种方法编译您的对象并使用 javap [XXX] 检查该类。 ,其中是对象或类的名称,在您的情况下 javap Stats2 .
您的第一种方法将给出:

public final class Stats2 extends java.lang.Object{
    public static final int variance$default$2();
    public static final double variance(scala.collection.Seq, int);
}

你的第二种方法将给出:
public final class Stats2 extends java.lang.Object{
    public static final int variance$default$2();
    public static final double variance(scala.collection.Seq, int, scala.Function1);
}

最后,通过删除第二种方法中 dof 的默认值,我们得到:
public final class Stats2 extends java.lang.Object{
    public static final double variance(scala.collection.Seq, int, scala.Function1);
}

所以static final int variance$default$2()是什么导致编译失败,这是由默认值生成的。

关于scala - 使用参数默认值键入删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18876059/

相关文章:

java - 通用功能接口(interface)和方法引用被类型删除弄乱了

c++ - 使用返回不完整类型的函数作为默认参数

Swift - 覆盖具有不同默认参数的函数

performance - 关闭 Actor 的 Future 接收方法中的 java.util.concurrent.ConcurrentHashMap 吗?

scala - datastax cassandra java 驱动程序与 scala 转换相关的问题(播放 2.3.x)

Scala 无法处理巨大的对象?

Scala无法解释的程序行为

linux - 服务器重启后,如何在 Linux 上的 Play 框架中自动运行我的 Scala 应用程序?

java - 如何根据 ChildType 对 java.util.ArrayList<ParentType> 进行排序?

python - "Least Astonishment"和可变默认参数