【问题标题】:Double Definition Error Despite Different Parameter Types尽管参数类型不同,但双重定义错误
【发布时间】:2013-07-24 18:26:35
【问题描述】:

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

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.depauw.scales.graphics.GraphicPanel 在第 115 行具有相同的类型 擦除后:(状态:对象,onRender:Function1,someOnKeyEvent: Function2) edu.depauw.scales.graphics.GraphicPanel

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

【问题讨论】:

    标签: scala types compiler-errors overloading


    【解决方案1】:

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

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

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

    【讨论】:

    • 为你的对象命名`Int => T disambiguator` 无助于丑陋程度(即使它对教育学很有价值):)
    • 我想我喜欢我的丑陋黑客一直丑陋!
    猜你喜欢
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 2015-12-11
    • 2021-10-03
    • 2020-07-07
    • 2021-12-13
    相关资源
    最近更新 更多