Scala String vs java.lang.String – type inference

En REPL, defino una función. Tenga en cuenta el tipo de devolución.

scala> def next(i: List[String]) = i.map {"0" + _} ::: i.reverse.map {"1" + _} next: (i: List[String])List[java.lang.String] 

Y si especifico el tipo de retorno como Cadena

 scala> def next(i: List[String]): List[String] = i.map {"0" + _} ::: i.reverse.map {"1" + _} next: (i: List[String])List[String] 

¿Por qué la diferencia? También puedo especificar el tipo de devolución como Lista [Cualquiera], así que supongo que String es solo un supertipo de envoltura para java.lang.String. ¿Esto tendrá alguna implicación práctica o puedo no especificar con seguridad el tipo de devolución?

¡Esta es una muy buena pregunta! Primero, déjame asegurarte que puedes especificar con seguridad el tipo de devolución.

Ahora, veamos … sí, cuando se deduce a la inferencia, Scala infiere java.lang.String , en lugar de solo String . Por lo tanto, si busca “Cadena” en ScalaDoc , no encontrará nada, lo que parece indicar que tampoco es una clase Scala. Bueno, tiene que venir de algún lugar, sin embargo.

Consideremos qué importa Scala de manera predeterminada. Puede encontrarlo usted mismo en el REPL:

 scala> :imports 1) import java.lang._ (155 types, 160 terms) 2) import scala._ (801 types, 809 terms) 3) import scala.Predef._ (16 types, 167 terms, 96 are implicit) 

Los dos primeros son paquetes, y, de hecho, ¡ String se puede encontrar en java.lang ! ¿Eso es todo? Comprobemos creando una instancia de otra cosa de ese paquete:

 scala> val s: StringBuffer = new StringBuffer s: java.lang.StringBuffer = scala> val s: String = new String s: String = "" 

Entonces, eso no parece ser así. Ahora bien, no puede estar dentro del paquete scala , o podría haberse encontrado al buscar en ScalaDoc. Así que echemos un vistazo al scala.Predef , ¡y ahí está!

 type String = String 

Eso significa que String es un alias para java.lang.String (que se importó anteriormente). Sin embargo, parece una referencia cíclica, pero si revisas la fuente , verás que está definida con la ruta completa:

 type String = java.lang.String 

A continuación, es posible que desee preguntar por qué? Bueno, no tengo idea, pero sospecho que es para hacer que una clase tan importante dependa un poco menos de la JVM.