Can someone explain what is going on here?
Here's the code:
scala> def foo(bar: Unit => String) = {bar}
foo: (bar: (Unit) => String)(Unit) => String
scala> foo(a => a.toString)
res0: (Unit) => String = <function1>
I am guessing a is of type Unit, but isn't Unit an object? Is the Unit class开发者_高级运维 hidden?
Unit
is an AnyVal
, like Int
. Its sole member is a literal, written as ()
. For example:
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 = ()
Working from your examples...
def foo(bar: Unit => String) = {bar}
This defines the foo
method, which accepts a function from Unit
to String
as its sole argument, and simply returns that same argument.
foo(a => a.toString)
a => a.toString
defines a function inline. Because the type inferencer knows that a function Unit => String
is expected at this location, it infers a
to be of type Unit
.
This invocation of foo
then returns the anonymous function that you just defined.
I'm curious, what exactly were you trying to achieve here? Or were you just exploring Scala's syntax?
In Scala Unit
is equivalent to Java's void
. You have defined a function that accepts another function with no parameters and returns a String
.
This is equivalent to def foo(bar: => String);
Or def foo(bar: () => String)
In Scala ()
is a shortcut for Unit
The answer given by Kevin Wright is entirely correct, but to break it down further:
The first line is declaring a function called foo
. foo
takes as its argument another function, bar
that itself takes in Unit
and returns a String
. Generally speaking, Unit
in scala has the same meaning that void
does in many other languages, so you could say for the most part that bar
is a function that takes in no arguments and returns a String
.
The body of the foo
function simply returns the argument it received. Therefore, scala infers that foo
returns a function that takes Unit
and returns a String
.
The second command calls foo
with the function a => a.toString
as its argument. a
is assumed to be of type Unit
. If Unit
was an exact analogue to void
, this wouldn't work. You can't call toString
on the absence of something. However, Unit
behaves slightly differently, exactly for situations like this, and a
will be given an instance of Unit
. This instance won't really be able to do much, but it will be able to have toString
called on it. So the result of the second command will be a function that returns the result of toString
called on the Unit
instance, which is:
"()"
精彩评论