inferenza scala con _ posto titolare
-
28-09-2019 - |
Domanda
List("This","is","Scala").foreach(a => print(a+" "))
compila bene, ma
List("This","is","Scala").foreach(print(_+" "))
fallisce lamentando di perdere tipo di parametro. Non riuscivo a capire perché non riesce.
EDIT:. Intendevo stampa non println - non che fa la differenza logica
Soluzione
Il problema è che questo
List("This","is","Scala").foreach(print(_+" "))
Non è equivalente a
List("This","is","Scala").foreach(a => print(a+" "))
ma per
List("This","is","Scala").foreach(print(a => a+" "))
Ora, vediamo la firma tipo di foreach
:
def foreach [B] (f: (A) ⇒ B) : Unit
dove A
è il parametro tipo di List
stesso. Dal momento che abbiamo un List[String]
, il compilatore sa si deve passare ad un foreach
Function[String, B]
.
In a => print(a+" ")
il tipo di a
è già noto quindi:. String
In print(a => a+" ")
c'è un problema, in quanto non è un print
Function
. Tuttavia, il compilatore non ha considerato che ancora - è ancora cercando di compilare a => a+" "
. Quindi cerchiamo di guardare al tipo di Predef.print
:
def print (x: Any) : Unit
Quindi a => a+" "
deve essere di tipo Any
, che, naturalmente, significa che può essere qualsiasi cosa. Non aiuta il compilatore in affermando ciò che il tipo di a
è. Il che non ha molta importanza, perché non si desidera stampare un Function
in primo luogo.
Altri suggerimenti
Scala legge (_+" ")
come x => x+" "
. Ma println
non contiene alcuna informazione di tipo per aiutare il compilatore indovinare quale tipo x
potrebbe essere, in modo che dà quell'errore.
Che cosa si voleva fare era notare che println
non ha funzionato e all'indietro recurse e provare di nuovo per foreach
. Ma non può farlo:. println
può prendere qualsiasi argomento, tra cui una funzione, in modo x => x+" "
è una cosa perfettamente valido per println
per provare a stampare
(E anche nel caso in cui si potrebbe in teoria backtrack, che in genere non lo fa.)