为什么 Scala 在使用按名称参数重载的情况下的行为与使用按值参数重载的情况不同?

发布于 2024-10-05 05:35:32 字数 470 浏览 7 评论 0原文

给定以下 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

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

Given this Scala code:

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

the call byval(5) compiles correctly, but byname fails to compile:

ambiguous reference to overloaded definition

Why? I would expect to observe the same behavior for by-value and by-name parameters with respect to overloading… How can it be fixed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏花。依旧 2024-10-12 05:35:33

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

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")
}

Possible workaround without overloading (in addition to what has been said earlier), if you don't want to use different method names:

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")
}
ヤ经典坏疍 2024-10-12 05:35:32

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

That's because JVM does not support a "by-name" parameter, so Scala has to implement it in another way. => X actually compiles to a Function0[X], which erases to Function0[Object], which makes it impossible for Scala to distinguish two methods that differ only by the expected type of a by-name parameter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文