2010-12-01 29 views
8

鑑於這種Scala代碼:爲什麼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)正確編譯,但綽號無法編譯:

ambiguous reference to overloaded definition 

爲什麼?我希望遵守相同的行爲,以適應超載的價值和名稱參數......它如何被修復?

+0

這可能是一個錯誤... – soc 2010-12-01 14:54:57

回答

13

這是因爲JVM不支持「by-name」參數,所以Scala必須以另一種方式實現它。 => X實際上編譯爲Function0[X],這會擦除到Function0[Object],這使得Scala無法區分兩種方法,這兩種方法僅根據名稱參數的預期類型而不同。

+0

感謝丹尼爾,這解釋了原因。現在怎麼能起作用(如果可能的話)? – 2010-12-01 14:36:02

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") 
} 
相關問題