This question already has an answer here:
- Scala foreach strange behaviour 5 answers
Scala lets you use an underscore to do a simple map. So for example instead of writing:
def roleCall(people: String*){
people.toList.map(x => println(x))
}
...I can instead write:
def roleCall(people: String*){
people.toList.map(println(_))
}
However for some reason I can't write:
def greet(people: String*){
// This won't compile!
people.toList.map(println("Hello " + _))
}
instead I have to write:
def greet(people: String*){
people.toList.map(x => println("Hello " + x))
}
Can anyone explain why?
Basically, the shorthand syntax for function definitions works as expected only if there are no nested parentheses. This is because each nesting level creates its own scope in which the underscores live. In the REPL, you can check for example that:
scala> val list = List(1,2,3).map(_ + 1)
list: List[Int] = List(2, 3, 4)
and
scala> val list = List(1,2,3).map((_ + 1))
list: List[Int] = List(2, 3, 4)
both work, but once you add anything after the parentheses, you get an error:
val list = List(1,2,3).map((_ + 1) + 1)
<console>:58: error: missing parameter type for expanded function ((x$1) => x$1.$plus(1))
val list = List(1,2,3).map((_ + 1) + 1)
As you see, the error pertains only to the function (_ + 1) (shown as ((x$1) => x$1.$plus(1))
in the message), not to the whole expression (_ + 1) + 1
so the part in parentheses is treated as a separate function and the underscore _
is interpreted in the scope of this inner function, not the external one.
I'm not really sure why List(1,2,3).map(println(_))
works but it seems to be some edge case which due to the single argument seems to just work by mere coincidence. I'd be happy myself to learn the details. Anyway, using parentheses inside anonymous function definitions with underscores is bound to cause trouble sooner or later and it's better to avoid it.
来源:https://stackoverflow.com/questions/26266413/underscores-and-string-concatenation-in-list-map-with-scala