2010-12-01 27 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") 
} 
相关问题