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実際には にコンパイルされFunction0[X]、これは に消去されFunction0[Object]ます。これにより、Scala は、名前によるパラメーターの期待される型だけが異なる 2 つのメソッドを区別できなくなります。

于 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 に答える