2010-08-16 17 views
7
List("This","is","Scala").foreach(a => print(a+" ")) 

fein kompiliert, aberscala Typinferenz mit _ Platzhalter

List("This","is","Scala").foreach(print(_+" ")) 

ausfällt beschwerte Parametertyp fehlt. Ich konnte nicht herausfinden, warum es fehlschlägt.

EDIT: Ich meinte drucken nicht println - nicht, dass es einen logischen Unterschied macht.

+2

Siehe http://stackoverflow.com/questions/2173373/scala-foreach-strange-behaviour/2176548#2176548 für eine detailliertere Antwort. – huynhjl

Antwort

7

Das Problem ist, dass diese

List("This","is","Scala").foreach(print(_+" ")) 

zu

nicht gleichwertig ist
List("This","is","Scala").foreach(a => print(a+" ")) 

aber zu

List("This","is","Scala").foreach(print(a => a+" ")) 

Nun wollen wir die Art Unterschrift von foreach sehen:

def foreach [B] (f: (A) ⇒ B) : Unit 

wo A der Typparameter des List selbst ist. Da wir eine List[String] haben, weiß der Compiler, dass man an foreach eine Function[String, B] übergeben muss.

In a => print(a+" ") die Art der a bereits dann bekannt ist: String.

In print(a => a+" ") gibt es ein Problem, wie print ist kein Function. Der Compiler hat dies jedoch noch nicht berücksichtigt - er versucht immer noch, a => a+" " zu kompilieren. Also schauen wir uns auf die Art der Predef.print:

def print (x: Any) : Unit 

So a => a+" "Any vom Typ sein muss, was natürlich bedeutet es kann alles sein. Es hilft dem Compiler nicht zu behaupten, was der Typ a ist. Was nicht wirklich wichtig ist, weil Sie keinen Function an erster Stelle drucken wollten.

6

Scala liest (_+" ") als x => x+" ". Aber println enthält keine Typinformation, um dem Compiler zu raten, welcher Typ x sein könnte, also gibt es diesen Fehler.

Was Sie war es Mitteilung machen wollte, dass println nicht und Rekursion rückwärts funktionierte und versuchen Sie es erneut für foreach. Aber es kann nicht tun: println kann jedes Argument, einschließlich einer Funktion, so x => x+" " ist eine vollkommen gültige Sache für println zu versuchen, zu drucken.

(Und selbst in einem Fall, in dem es in der Theorie Rückzieher könnte, es in der Regel nicht.)