To jest bardzo dobre pytanie! Po pierwsze, zapewniam, że możesz bezpiecznie określić typ zwrotu.
Teraz, spójrzmy w to ... tak, kiedy zostawiamy wniosek, Scala podaje java.lang.String
, zamiast tylko String
. Tak więc, jeśli spojrzysz na "String" w ScalaDoc, nie znajdziesz niczego, co zdaje się wskazywać, że to też nie jest klasa Scala. Musi jednak pochodzić z jakiegoś miejsca.
Zastanówmy się, co Scala domyślnie importuje. Można go znaleźć przez siebie na 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)
Pierwsze dwa są pakiety - i rzeczywiście, String
można znaleźć na java.lang
! Czy to w takim razie? Sprawdźmy, tworząc instancję z tej paczki:
scala> val s: StringBuffer = new StringBuffer
s: java.lang.StringBuffer =
scala> val s: String = new String
s: String = ""
To chyba nie jest to. Teraz nie może być w pakiecie scala
, lub zostałby znaleziony podczas wyszukiwania w ScalaDoc. Zajrzyjmy więc do środka scala.Predef
, i oto jest!
type String = String
Oznacza to String
jest ps do java.lang.String
(co zostało importowane wcześniej). Że wygląda cyklicznego odniesienia chociaż, ale jeśli sprawdzić source, zobaczysz, że jest określona z pełną ścieżką:
type String = java.lang.String
Następnie warto zapytać dlaczego? Cóż, nie mam pojęcia, ale podejrzewam, że tak ważną klasą jest mniej zależna od JVM.
To trochę dziwne, że literały łańcuchowe są uważane za typu java.lang.String, gdy wydaje się, że równie dobrze można wywnioskować, że są typu String. Ale miło wiedzieć, że to dokładnie to samo. –
@Luigi To dlatego, że literały _ są_ typu java.lang.String. Tak naprawdę nie ma tu żadnej konkluzji - są to literały. –
Może najczystsza, najlepsza, dobrze zaplanowana odpowiedź, jaką kiedykolwiek widziałem na SO. Tak odświeżający. Dzięki, Daniel – jbnunn