Tipo de Scala inferencia con _ lugar titular
-
28-09-2019 - |
Pregunta
List("This","is","Scala").foreach(a => print(a+" "))
compila bien, pero
List("This","is","Scala").foreach(print(_+" "))
falla quejándose de la falta de tipo de parámetro. Yo no podía entender por qué no funciona.
EDIT:. Me refería impresión no PRINTLN - no es que hace diferencia lógica
Solución
El problema es que este
List("This","is","Scala").foreach(print(_+" "))
no es equivalente a
List("This","is","Scala").foreach(a => print(a+" "))
pero a
List("This","is","Scala").foreach(print(a => a+" "))
Ahora, vamos a ver la firma tipo de foreach
:
def foreach [B] (f: (A) ⇒ B) : Unit
donde A
es el parámetro de tipo de la propia List
. Puesto que tenemos una List[String]
, el compilador sabe que uno tiene que pasar a un foreach
Function[String, B]
.
En a => print(a+" ")
del tipo de a
ya se conoce a continuación:. String
En print(a => a+" ")
hay un problema, ya que no es un print
Function
. Sin embargo, el compilador no ha considerado que aún - está todavía tratando de recopilar a => a+" "
. Así que vamos a ver el tipo de Predef.print
:
def print (x: Any) : Unit
Así a => a+" "
debe ser del tipo Any
, que, por supuesto, significa que puede ser cualquier cosa. No ayuda el compilador al afirmar lo que el tipo de a
es. El cual en realidad no importa, porque no desea imprimir una Function
en primer lugar.
Otros consejos
Scala lee (_+" ")
como x => x+" "
. Pero println
no contiene ningún tipo de información para ayudar al compilador conjetura qué tipo x
podría ser, por lo que da ese error.
Lo que quisiera que hiciera era aviso de que println
no funcionaba y hacia atrás recurse y probarlo de nuevo por foreach
. Pero no puede hacerlo:. println
puede tomar cualquier argumento, incluyendo una función, por lo x => x+" "
es una cosa perfectamente válido para println
para tratar de imprimir
(E incluso en un caso en el que podría dar marcha atrás en teoría, por lo general, no lo hace.)