scala - 尽管参数类型不同,但双重定义错误

标签 scala types compiler-errors overloading

我收到以下两种方法的双重定义错误:

def apply[T](state: T, onRender: T => Graphic,
             onMouseEvent: (MouseEvent, T) => T): GraphicPanel = 
  apply(state, onRender, onMouseEvent = Some(onMouseEvent))

def apply[T](state: T, onRender: T => Graphic,
             onKeyEvent: (KeyEvent, T) => T): GraphicPanel = 
  apply(state, onRender, onKeyEvent = Some(onKeyEvent))

它们都是更通用的 apply 方法的方法重载,带有签名:

def apply[T](state: T, onRender: T => Graphic,
             onTickEvent: Option[T => T] = None, fps: Int = 30,
             onMouseEvent: Option[(MouseEvent, T) => T] = None,
             onMouseMotionEvent: Option[(MouseEvent, T) => T] = None,
             onMouseInputEvent: Option[(MouseEvent, T) => T] = None,
             onKeyEvent: Option[(KeyEvent, T) => T] = None)

我会假设即使类 KeyEventMouseEvent 有一个共同的父类(super class) (InputEvent),编译器仍然应该能够来区分它们。但是,它正在抛出错误:

double definition: method apply:[T](state: T, onRender: T => edu.depauw.scales.graphics.Graphic, someOnKeyEvent: (java.awt.event.KeyEvent, T) => T)edu.depauw.scales.graphics.GraphicPanel and method apply:[T](state: T, onRender: T => edu.depauw.scales.graphics.Graphic, onMouseEvent: (java.awt.event.MouseEvent, T) => T)edu.depauw.scales.graphics.GraphicPanel at line 115 have same type after erasure: (state: Object, onRender: Function1, someOnKeyEvent: Function2) edu.depauw.scales.graphics.GraphicPanel

有人知道发生了什么吗?诚然,我不知道短语“删除后”是什么意思,所以解释一下它的工作原理可能会有所帮助。

最佳答案

这是一个显示相同问题的更简单示例:

object Example {
  def foo[T](f: Int => T) = ???
  def foo[T](f: String => T) = ???
}

在将 => 符号脱糖后,这相当于以下内容:

object Example {
  def foo[T](f: Function[Int, T]) = ???
  def foo[T](f: Function[String, T]) = ???
}

问题在于 Java 虚拟机 doesn't know about generics (在 Scala 或 Java 中),所以它认为这两种方法如下:

object Example {
  def foo[T](f: Function) = ???
  def foo[T](f: Function) = ???
}

这显然是个问题。

这是 many reasons 之一避免Scala中的方法重载。如果这不是一个选项,您可以使用以下技巧:

object Example {
  implicit object `Int => T disambiguator`
  implicit object `String => T disambiguator`

  def foo[T](f: Int => T)(implicit d: `Int => T disambiguator`.type) = ???
  def foo[T](f: String => T)(implicit d: `String => T disambiguator`.type) = ???
}

在用法上看起来相同,但显然非常可怕。

关于scala - 尽管参数类型不同,但双重定义错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17841993/

相关文章:

haskell - Haskell 中类型参数的正确类型签名

android - 启动 Android 程序时出错

node.js - 关于不兼容类型的 Typescript 编译器错误

java - Spark 2.0 中的字符串、数据集对

scala - 如何匹配但不消耗 Akka HTTP 中的路径前缀?

scala - 在 Shapeless 中实现路径相关的 map 类型

function - Julia:效率和指示参数类型

Scala:解决 "illegal cyclic reference"

compiler-errors - 处理词法分析中的错误

string - Scala String 与 java.lang.String - 类型推断