为什么我不能覆盖在Scala中将值类作为参数的方法?

时间:2014-07-23 10:45:38

标签: scala override value-class

我正在使用Scala 2.10.3中的值类(扩展AnyVal的类),但在将它们用作抽象方法的参数时会遇到奇怪的编译器错误。 如下例所示:

class ValueClass(val x: Int) extends AnyVal

trait Test {
  def foo(v: ValueClass): Int
}

new Test {
  override def foo(v: ValueClass): Int = 1
}

编译器会发出以下错误:

error: bridge generated for member method foo: (v: ValueClass)Int in anonymous class $anon
which overrides method foo: (v: ValueClass)Int in trait Test
clashes with definition of the member itself;
both have erased type (v: Int)Int
          override def foo(v: ValueClass): Int = 1

为什么这不起作用?有没有办法将值类传递给抽象方法?

1 个答案:

答案 0 :(得分:2)

正如其他人所说,此问题已在以后的版本中修复。如果您对所发生的变化感到好奇,建议您查看pull request

  

SI-6260避免使用lambdas而不是值类的双重定义错误将方法签名中的值类重新擦除到底层   当擦除的签名与泛型重叠时,类型会造成严重破坏   来自重写方法的签名。两者都没有空间。   但我们真的需要两者兼顾;接口方法的调用者将是   传递桥接需要拆箱并传递给的盒装值   接受未装箱值的特定方法。

     

这通常会出现擦除为Object的值类   用作参数或匿名的返回类型   功能

     

这被认为是难以处理的,除非我们选择了不同的   子类中未装箱的特定方法的名称。但听起来   像一个需要调用网站重写的大任务,ala   专业化。

     

但是有一个重要的特殊情况我们不需要   重写呼叫站点。如果定义方法的类是匿名的,   实际上没有必要使用未装箱的方法;它只会   通过通用方法调用。

     

在研究Java 8 lambdas是如何实现时,我开始意识到这一点   处理。我期待桥接方法,但没有找到。 lambda   body直接放在一个与泛型完全匹配的方法中   签名。

     

此提交检测桥和目标之间的冲突,并恢复   对于匿名类,通过修改目标方法的名称   符号。这用作字节码名称。通用桥梁前进   与之前一样,使用必要的box / unbox操作。