为什么以及何时需要使用_跟随方法名称?

Mat*_*t R 12 scala partial-application

关于什么时候你需要_一个方法来使用它作为一个函数,我对规则有点不稳定.例如,为什么以下的Foo's和Nil's 之间存在差异::

def square(n: Int) = n * n  
object Foo { def ::(f: Int => Int) = f(42) }

// ...

scala> Foo.::(square)
res2: Int = 1764

scala> Nil.::(square) 
<console>:6: error: missing arguments for method square in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
   Nil.::(square)
          ^
scala> Nil.::(square _) 
res3: List[(Int) => Int] = List(<function1>)
Run Code Online (Sandbox Code Playgroud)

Ben*_*mes 15

省略部分应用的函数表达式中的所有参数时,_ 除非编译器在您使用它的位置需要函数类型,否则需要使用它.

当您打开方法::Foo,编译器需要Int => Int参数的类型.因此,您可以square在该位置后安全地省略下划线.

但是,::方法on Nil可以采用任何类型的参数.因此,不要假设您打算部分应用该函数,它会抱怨,除非您通过添加使其绝对明确_.

所以那些是规则......我无法真正启发你为什么这些是规则; 也许对编译器,类型系统和语言设计有更好了解的其他人将能够告诉你原因.但我认为,如果没有这些规则,很多地方都会出现意外模糊的危险.

  • 谢谢.刚刚发现了Scala语言规范的一部分,它为"为什么"提供了一些理由,在Scala 2.0的更改说明中:"函数方法的隐式转换规则(§6.25)已经收紧.以前,使用了参数化方法因为值总是隐式转换为函数.当方法参数被遗忘时,这可能会导致意外的结果.例如,考虑以下语句:show(x.toString)..." (2认同)