我在以下两种方法上收到双重定义错误:
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)
我认为即使类KeyEvent
和MouseEvent
具有共同的超类(InputEvent
),编译器仍应能够区分它们。但是,它正在抛出错误:
双重定义:方法适用:[T](状态:T,onRender:T => edu.depauw.scales.graphics.Graphic,someOnKeyEvent: (java.awt.event.KeyEvent,T)=> T)edu.depauw.scales.graphics.GraphicPanel和方法适用:[T](状态: T,onRender:T => edu.depauw.scales.graphics.Graphic,onMouseEvent: (java.awt.event.MouseEvent,T)=> T)第115行的edu.depauw.scales.graphics.GraphicPanel具有相同的类型 擦除后:(状态:对象,onRender:Function1,someOnKeyEvent: 功能2)edu.depauw.scales.graphics.GraphicPanel
任何人都知道发生了什么事?不可否认,我不知道删除后的短语“是什么意思,所以也许对其工作方式的解释可能会有所帮助。
答案 0 :(得分:8)
这是一个更简单的示例,显示了同样的问题:
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) = ???
}
这显然是一个问题。
这是避免Scala中方法重载的many reasons之一。如果这不是一个选项,你可以使用如下的技巧:
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) = ???
}
看起来用法相同,但显然很可怕。