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



我在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

为什么这个不行?是否有一种方法可以将值类传递到抽象方法中?

所以正如其他人注意到的,这个问题在以后的版本中已经修复了。如果你对改动了什么感到好奇,我建议你看看这个pull request。

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

这通常出现在擦除对象的值类中类的参数或返回类型函数。

这被认为是难以解决的,除非我们选择不同的方法子类中未装箱的特定方法的名称。但这听起来就像一个需要重写呼叫站点的大任务专业化。

但是有一个重要的特殊情况,我们不需要重写呼叫站点。如果定义该方法的类是匿名的,实际上不需要unboxed方法;它永远只会通过泛型方法调用。

我是在观察Java 8的lambdas时意识到这一点的处理。我期待桥接方法,但没有找到。λBody直接放置在与泛型完全匹配的方法中签名。

这个commit检测到bridge和target之间的冲突,并恢复通过混淆目标方法的名称来获取匿名类的象征。这被用作字节码的名称。通用桥接向前与前面一样,使用必要的box/unbox操作。

相关内容

  • 没有找到相关文章

最新更新