Почему и когда мне нужно следовать имени метода с _? - PullRequest
12 голосов
/ 14 января 2010

Я немного неуверен в правилах относительно того, когда вам нужно _ после метода, чтобы использовать его как функцию. Например, почему существует разница между Foo и Nil * :: в следующем?

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

1 Ответ

15 голосов
/ 14 января 2010

Когда вы опускаете все параметры в частично примененном выражении функции, вам нужно следовать за ним с _ , если компилятору не требуется тип функции в месте, где вы используете это.

Когда вы вызываете метод :: для Foo, компилятор ожидает тип Int => Int для параметра. Таким образом, вы можете смело опускать подчеркивание после square в этой позиции.

Однако метод :: в Nil может принимать параметр любого типа . Поэтому вместо того, чтобы предполагать, что вы хотели частично применить функцию, она будет жаловаться, если вы не сделаете ее абсолютно явной, добавив _.

Итак, это правила ... Я не могу вас просветить о почему это правила; Может быть, кто-то еще, кто лучше знает компилятор, систему типов и дизайн языка, сможет сказать вам, почему. Но я предполагаю, что без этих правил во многих местах возникнет опасность случайной двусмысленности.

...