Scala Строка vs java.lang.String - вывод типа

В REPL я определяю функцию. Обратите внимание на тип возврата.

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

И если я укажу тип возврата как String

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

Почему разница? Я также могу указать тип возвращаемого значения как List [Any], поэтому я предполагаю, что String - это просто супертип оболочки для java.lang.String. Будет ли это иметь какие-либо практические последствия или я могу безопасно не указывать тип возврата?

Ответ 1

Это очень хороший вопрос! Во-первых, позвольте мне заверить вас, что вы можете безопасно указать тип возврата.

Теперь, давайте посмотрим на это... да, когда выходите на вывод, Scala выводит java.lang.String, а не просто String. Итак, если вы посмотрите "String" в ScalaDoc, вы ничего не найдете, что, по-видимому, указывает, что это не класс Scala. Ну, это должно произойти откуда-то, хотя.

Давайте рассмотрим, что импортирует Scala по умолчанию. Вы можете найти его самостоятельно на 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)

Первые два пакета - и, действительно, String можно найти на java.lang! Значит, это так? Пусть проверяет, создавая что-то еще из этого пакета:

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

scala> val s: String = new String
s: String = ""

Таким образом, похоже, это не так. Теперь он не может находиться внутри пакета scala, или он был бы найден при поиске ScalaDoc. Итак, загляните внутрь scala.Predef, и вот оно!

type String = String

Это означает, что String является псевдонимом для java.lang.String (который ранее был импортирован). Это похоже на циклическую ссылку, но если вы проверите источник , вы увидите, что он определен с полным путем:

type String        = java.lang.String

Затем вы можете спросить, почему? Ну, я понятия не имею, но я подозреваю, что сделать такой важный класс немного менее зависимым от JVM.