I have code below:
test("temp") {
def greeting(func: (String) => Unit, name: String) {
func(name)
}
// Success
greeting(println(_), "Hello")
greeting( { case _ => println("" + `_`) }, "Hello")
// Failed
greeting(println("" + _), "Hello")
greeting(println("a"), "Hello")
}
The error message is:
Error:(52, 29) type mismatch;
found : Unit
required: String => Unit
greeting(println("" + _), "Hello")
Error:(53, 29) type mismatch;
found : Unit
required: String => Unit
greeting(println("a"), "Hello")
^
I don't understand it very well. What's the different between println("" + _) and (String) => Unit? and why println("a") has not been treated as (String) => Unit also but println(_) does?
Statement 1
greeting(println(_), "Hello") // placeholder syntax
Above is a short form of function literal called placeholder syntax. It is expanded like:
greeting(x => println(x), "Hello")
Statement 2
greeting( { case _ => println("" + `_`) }, "Hello") // wildcard pattern
case _
is a wild card pattern. You can not use _
again. If you want to use case
clause, you should use variable matching:
greeting( { case x => println("" + x) }, "Hello")
Statements 3 & 4
greeting(println("" + _), "Hello")
greeting(println("a"), "Hello")
Note that "" + _
in println("" + _)
, itself is an anonymous function. So println("" + _)
is considered as an expression.
Compiler treats both, println("" + _)
and println("a")
as an expression, not as function literal passed as parameter. So it tries to evaluate println("" + _)
and println("a")
first, then passes result (Unit
) to greeting
, hence compilation error.