9

鉴于此 Scala 代码:

object test {

  def byval(a: Int) = println("Int")
  def byval(a: Long) = println("Long")

  def byname(a: => Int) = println("=> Int")
  def byname(a: => Long) = println("=> Long")

  def main(args: Array[String]) {
      byval(5)
      byname(5)
  }
}

调用 byval(5) 编译正确,但 byname 编译失败:

ambiguous reference to overloaded definition

为什么?我希望在重载方面观察到按值和按名称参数的相同行为……如何解决?

4

2 回答 2

14

那是因为 JVM 不支持“按名称”参数,所以 Scala 必须以另一种方式实现它。=> X实际上编译为 a Function0[X],它擦除为Function0[Object],这使得 Scala 无法区分两种方法,这两种方法仅在预期类型的​​别名参数上有所不同。

于 2010-12-01T14:31:20.030 回答
6

如果您不想使用不同的方法名称,则无需重载的可能解决方法(除了前面所说的):

def byname[A](a: => A)(implicit manifest:Manifest[A]) = 
manifest.erasure match {
   case erasure if(erasure.isAssignableFrom(classOf[Long])) => println("=> Long")
   case erasure if(erasure.isAssignableFrom(classOf[Int])) => println("=> Int")
}
于 2010-12-01T15:02:17.020 回答