Pourquoi et quand dois-je suivre un nom de méthode avec _?
-
20-09-2019 - |
Question
Je suis un peu fragile sur les règles que lorsque vous avez besoin d'un _
après une méthode pour l'utiliser en fonction. Par exemple, pourquoi est-il une différence entre ce Foo
et la Nil
de ::
dans ce qui suit?
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>)
La solution
Lorsque vous ne spécifiez pas tous les paramètres dans une expression de fonction partiellement appliquée, alors vous devez suivre avec _
à moins que le compilateur nécessite un type de fonction dans l'endroit où vous utilisez il.
Lorsque vous appelez la méthode ::
sur Foo
, le compilateur attend un type Int => Int
pour le paramètre. Ainsi, vous pouvez en toute sécurité omettre le trait de soulignement après square
dans cette position.
Cependant, la méthode de ::
sur Nil
peut prendre un paramètre de any de type. Ainsi, plutôt que de supposer que vous vouliez dire appliquer partiellement la fonction, il se plaint à moins que vous le rendre absolument explicite en ajoutant _
.
Donc, ce sont les règles ... Je ne peux pas vraiment vous éclairer sur pourquoi ce sont les règles; peut-être quelqu'un d'autre qui a une meilleure connaissance du compilateur, le système de type, et la conception de la langue sera en mesure de vous dire pourquoi. Mais je suppose que, sans ces règles, il y aurait un risque d'ambiguïté accidentelle dans de nombreux endroits.