理解Scala中的类型推理

St.*_*rio 7 methods scala

我写了以下简单的程序:

import java.util.{Set => JavaSet}
import java.util.Collections._

object Main extends App {
    def test(set: JavaSet[String]) = ()

    test(emptySet()) //fine
    test(emptySet) //error
}
Run Code Online (Sandbox Code Playgroud)

DEMO

并且真的很惊讶最后一行test(emptySet)没有编译.为什么?有什么区别test(emptySet())?我认为在Scala中我们可以在这种情况下自由省略括号.

Ale*_*nov 4

请参阅方法转换Scala 规范中的

\n\n
\n

以下四种隐式转换可应用于不适用于某些参数列表的方法。

\n\n

评估

\n\n

类型 => T 的无参数方法 m\n 始终通过计算 m 所绑定到的表达式来转换为类型 T。

\n\n

隐式应用程序

\n\n

如果该方法仅采用隐式参数,则按照此处的规则传递隐式参数。

\n\n

埃塔扩张

\n\n

否则,如果该方法不是构造函数,并且预期类型 pt\n 是函数类型 (Ts\xe2\x80\xb2)\xe2\x87\x92T\xe2\x80\xb2,则对表达式 e.

\n\n

空申请

\n\n

否则,如果 e\n 具有方法类型 ()T,则它会隐式应用于空参数列表,产生 e()。

\n
\n\n

您想要的是“空应用程序”,但只有在没有任何早期转换的情况下才应用它,在这种情况下,会发生“Eta 扩展”。

\n\n

编辑:这是错误的,@Jasper-M\ 的评论是正确的。没有发生 eta 扩展,“空应用程序”目前不适用于泛型方法。

\n

  • 严格来说,“emptySet”没有方法类型“()JavaSet[T]”,而是方法类型“[T]()JavaSet[T]”。 (2认同)
  • 哎呀。当然你是对的,我的答案是错误的,因为我设法将报告的类型与 `() => JavaSet[T]` 混淆了(尽管看了很多次)。这里没有 eta 扩展,因此没有错误(但也许有改进的地方)。 (2认同)