尽管参数类型不同,但双定义错误 [英] Double Definition Error Despite Different Parameter Types

查看:81
本文介绍了尽管参数类型不同,但双定义错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm receiving a double definition error on the following two methods:

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方法的方法重载:

which are both method overloads for the more general apply method with the signature:

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),编译器仍应能够区分它们.但是,它会引发错误:

I would assume that a even though the classes KeyEvent and MouseEvent have a common superclass (InputEvent), the compiler should still be able to distinguish between them. However, it is throwing the error:

双重定义:方法适用:[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)=> 第115行的T)edu.depauw.scales.graphics.GraphicPanel具有相同的类型 擦除后:(状态:对象,onRender:Function1,someOnKeyEvent: Function2)edu.depauw.scales.graphics.GraphicPanel

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

任何人都知道发生了什么事吗?诚然,我不知道短语擦除后"是什么意思,所以也许对它的工作方式进行解释可能会有所帮助.

Anyone have any idea what is going on? Admittedly, I don't know what is meant by the phrase "after erasure", so maybe an explanation of how that works might be helpful.

推荐答案

下面是一个显示相同问题的简单示例:

Here's a simpler example that shows the same issue:

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

在将=>符号废除后,这等效于以下内容:

This is equivalent to the following, after desugaring the => symbols:

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

问题是Java虚拟机不了解泛型(在Scala或Java中),因此它将以下两种方法视为:

The problem is that the Java Virtual Machine doesn't know about generics (in either Scala or Java), so it sees these two methods as the following:

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

这显然是个问题.

这是许多原因之一,以避免在Scala中方法重载.如果这不是一个选择,则可以使用以下技巧:

This is one of many reasons to avoid method overloading in Scala. If that's not an option, you could use a trick like the following:

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

在用法上看起来相同,但是显然很丑陋.

Which looks the same usage-wise, but is obviously pretty hideous.

这篇关于尽管参数类型不同,但双定义错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆