Scala eta表达式模糊引用未列出所有重载方法

时间:2018-02-16 14:04:59

标签: scala

我正在使用Scala 2.12.1。在口译员中我做了一个Int val:

scala> val someInt = 3
someInt: Int = 3

然后我尝试使用eta扩展并收到以下错误:

scala> someInt.== _
<console>:13: error: ambiguous reference to overloaded definition,
both method == in class Int of type (x: Char)Boolean
and  method == in class Int of type (x: Byte)Boolean
match expected type ?
       someInt.== _
               ^

我在the scaladoc中看到Int类有超过2个重载方法。

问题:是否有一个特殊原因,错误消息只显示2个重载方法,而不是列出所有这些方法?

顺便说一下,要指定要使用哪种方法的语法是:

scala> someInt.== _ : (Double => Boolean)
res9: Double => Boolean = $$Lambda$1103/1350894905@65e21ce3

1 个答案:

答案 0 :(得分:0)

列出的两种方法的选择似乎或多或少是任意的。例如,此代码段:

class A
class B
class C

class Foo {
  def foo(thisWontBeListed: C): Unit = {}
  def foo(thisWillBeListedSecond: B): Unit = {}
  def foo(thisWillBeListedFirst: A): Unit = {}
}

val x: Foo = new Foo
x.foo _

无法使用错误消息进行编译:

error: ambiguous reference to overloaded definition,
both method foo in class Foo of type (thisWillBeListedFirst: this.A)Unit
and  method foo in class Foo of type (thisWillBeListedSecond: this.B)Unit
match expected type ?
    x.foo _

也就是说,它只是选择已添加到类主体的最后两个方法,并在错误消息中列出它们。也许这些方法以相反的顺序存储在List中,然后选择两个第一项来组成错误消息。

为什么这样做?它做到了,因为它已被编程为这样做,我把它作为一个给定的事实。

为什么编程完成这个而不是别的东西的主要原因是什么?这可能是一个主要基于意见的问题,除了Scala编译器的作者本身可能没有人能给出明确答案。我可以想到至少有三个很好的理由,为什么只列出了两种冲突的方法:

  • 它更快:为什么搜索所有冲突,如果已经清楚某个特定代码行不能编译?没有理由浪费任何时间列举特定代码行可能出错的所有可能方式。
  • 通常不需要完整的冲突方法列表:错误消息已经很长了,有时可能有点神秘。为什么通过为一行打印整个错误消息墙来加剧它?
  • 实现更容易:每当您编写某种语言解释器时,您很快就会注意到返回所有错误比返回只是第一个错误要困难一些。也许在这种特殊情况下,决定不打算收集所有可能的冲突。

PS:the source code of Int中方法的顺序似乎有所不同,但我并不确切知道这个&#34;来源&#34;代码与实际的Int实现有关:它似乎是一个没有任何实现的生成文件,它只是为了@scaladoc有一些东西需要处理,真正的实现在其他地方。