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

Posted

技术标签:

【中文标题】Scala eta 表达式模糊引用未列出所有重载方法【英文标题】:Scala eta expression ambiguous reference doesn't list all overloaded methods 【发布时间】:2018-07-27 11:11:00 【问题描述】:

我使用的是 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

【问题讨论】:

或者这个:someInt == (_: Double) @AndreyTyukin 非常感谢 【参考方案1】:

列出的两种方法的选择似乎或多或少是任意的。比如这个sn-p:

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 中方法的顺序似乎不同,但我不知道这个“源”代码与实际的Int 实现有什么关系:它似乎是一个生成的文件没有任何实现,它的存在只是为了让@scaladoc 有一些东西要处理,真正的实现在别处。

【讨论】:

以上是关于Scala eta 表达式模糊引用未列出所有重载方法的主要内容,如果未能解决你的问题,请参考以下文章

Scala 列表:为啥 IDEA 提示未使用的表达式没有副作用

重学scala:scala中的变量方法函数

使用卡方检验列出语料库中拒绝原假设的所有单词

c++中为啥赋值运算符重载返回类型是引用

VC++2010 中的编译器错误(2008 年干净!),“对重载函数的模糊调用”

引用模板类型的赋值运算符需要非常量重载