3

次の 2 つのメソッドで二重定義エラーが発生します。

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が共通のスーパークラス ( InputEvent) を持っていても、コンパイラはそれらを区別できるはずです。ただし、次のエラーがスローされます。

二重定義: メソッド apply:[T](state: T, onRender: T => edu.depauw.scales.graphics.Graphic, someOnKeyEvent: (java.awt.event.KeyEvent, T) => T)edu.depauw. scales.graphics.GraphicPanel とメソッド apply:[T](state: T, onRender: T => edu.depauw.scales.graphics.Graphic, onMouseEvent: (java.awt.event.MouseEvent, T) => T)edu 115 行目の .depauw.scales.graphics.GraphicPanel は、消去後に同じ型になります: (state: Object, onRender: Function1, someOnKeyEvent: Function2) edu.depauw.scales.graphics.GraphicPanel

何が起こっているのか誰にも分かりますか?確かに、 「消去後」というフレーズの意味がわからないので、それがどのように機能するかの説明が役立つかもしれません。

4

1 に答える 1

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 仮想マシンがジェネリック(Scala または Java のいずれか) を認識しないため、これら 2 つのメソッドを次のように認識することです。

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

これは明らかに問題です。

これは、Scala でメソッドのオーバーロードを避けるべき多くの理由の 1 つです。それができない場合は、次のようなトリックを使用できます。

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) = ???
}

使い方は同じように見えますが、明らかにかなり恐ろしいものです。

于 2013-07-24T18:51:16.773 に答える