¿Alguien puede explicar lo que está pasando aquí?
Pregunta
Aquí está el código:
scala> def foo(bar: Unit => String) = {bar}
foo: (bar: (Unit) => String)(Unit) => String
scala> foo(a => a.toString)
res0: (Unit) => String = <function1>
Supongo que una unidad es de tipo, pero ¿no es la unidad un objeto? ¿Está oculta la clase de unidad?
Solución
Unit
es un AnyVal
, me gusta Int
. Su único miembro es literal, escrito como ()
. Por ejemplo:
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 = ()
Otros consejos
Trabajando a partir de sus ejemplos ...
def foo(bar: Unit => String) = {bar}
Esto define el foo
método, que acepta una función de Unit
a String
como su único argumento, y simplemente devuelve ese mismo argumento.
foo(a => a.toString)
a => a.toString
Define una función en línea. Porque el tipo de infierno sabe que una función Unit => String
se espera en este lugar, infiere a
ser de tipo Unit
.
Esta invocación de foo
Luego devuelve la función anónima que acaba de definir.
Tengo curiosidad, ¿qué estaba tratando exactamente de lograr aquí? ¿O simplemente estabas explorando la sintaxis de Scala?
En Scala Unit
es equivalente a Java's void
. Ha definido una función que acepta otra función sin parámetros y devuelve un String
.
Esto es equivalente a def foo(bar: => String);
O def foo(bar: () => String)
En Scala ()
es un atajo para Unit
La respuesta dada por Kevin Wright es completamente correcta, pero para desglosarla aún más:
La primera línea es declarar una función llamada foo
. foo
toma como argumento otra función, bar
que en sí mismo toma Unit
y devuelve un String
. Generalmente hablando, Unit
en Scala tiene el mismo significado de que void
en muchos otros idiomas, por lo que se podría decir en su mayor parte que bar
es una función que no toma argumentos y devuelve un String
.
El cuerpo del foo
La función simplemente devuelve el argumento que recibió. Por lo tanto, Scala infiere que foo
Devuelve una función que toma Unit
y devuelve un String
.
El segundo comando llama foo
con la función a => a.toString
como su argumento. a
se supone que es de tipo Unit
. Si Unit
fue un análogo exacto a void
, esto no funcionaría. No puedes llamar toString
en ausencia de algo. Sin embargo, Unit
se comporta de manera ligeramente diferente, exactamente para situaciones como esta, y a
se le dará una instancia de Unit
. Esta instancia realmente no podrá hacer mucho, pero podrá tener toString
lo llamó. Entonces, el resultado del segundo comando será una función que devuelva el resultado de toString
llamado al Unit
instancia, que es: "()"