Quelqu'un peut-il expliquer ce qui se passe ici?
Question
Voici le code:
scala> def foo(bar: Unit => String) = {bar}
foo: (bar: (Unit) => String)(Unit) => String
scala> foo(a => a.toString)
res0: (Unit) => String = <function1>
Je suppose un est de type unité, mais n'est pas un objet Unité? Est la classe d'unité cachée?
La solution
Unit
est un AnyVal
, comme Int
. Son seul membre est un littéral, écrit ()
. Par exemple:
scala> def foo(bar: Unit => String) = {bar}
foo: (bar: Unit => String)Unit => String
scala> foo(a => a.toString)
res0: Unit => String = <function1>
scala> res0(())
res1: String = ()
Autres conseils
travail de vos exemples ...
def foo(bar: Unit => String) = {bar}
Ceci définit la méthode de foo
, qui accepte une fonction de Unit
à String
comme argument unique, et renvoie simplement le même argument.
foo(a => a.toString)
a => a.toString
définit une ligne de fonction. Parce que le type inferencer sait qu'une Unit => String
fonction est attendue à cet endroit, il infère a
être de type Unit
.
Cette invocation de foo
retourne alors la fonction anonyme que vous venez de définir.
Je suis curieux, quels étaient exactement vous essayer d'obtenir ici? Ou vous venez explorer la syntaxe de Scala?
Dans Scala Unit
est équivalent à void
de Java. Vous avez défini une fonction qui accepte une autre fonction sans paramètre et retourne un String
.
Cela équivaut à def foo(bar: => String);
Ou def foo(bar: () => String)
Dans Scala ()
est un raccourci pour Unit
La réponse donnée par Kevin Wright est tout à fait correct, mais pour le décomposer plus:
La première ligne est une fonction appelée déclarant foo
. foo
prend comme argument une autre fonction, bar
qui se prend en Unit
et retourne un String
. D'une manière générale, Unit
dans scala a la même signification que void
fait dans beaucoup d'autres langues, donc on peut dire pour la plupart que bar
est une fonction qui prend en aucun argument et retourne un String
.
Le corps de la fonction foo
retourne simplement l'argument qu'il a reçu. Par conséquent, scala déduit que foo
retourne une fonction qui prend Unit
et retourne un String
.
La deuxième commande appelle foo
avec la fonction a => a.toString
comme argument. a
est supposé être de type Unit
. Si Unit
était un analogue exact void
, cela ne fonctionnerait pas. Vous ne pouvez pas appeler toString
sur l'absence de quelque chose. Cependant, Unit
se comporte de façon légèrement différente, exactement pour les situations comme celle-ci, et a
sera donnée une instance de Unit
. Cette instance ne sera pas vraiment être en mesure de faire beaucoup, mais il sera en mesure d'avoir toString
appelé là-dessus. Ainsi, le résultat de la deuxième commande sera une fonction qui renvoie le résultat de toString
appelé l'instance Unit
, qui est:
"()"