web-dev-qa-db-ja.com

Scala String 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]

そして、戻り値の型を文字列として指定した場合

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のラッパースーパータイプにすぎないと思います。これには実際的な意味がありますか、それとも戻り値の型を安全に指定できませんか?

41
Luigi Plinge

これはとても良い質問です!まず、戻り値の型を安全に指定できることを確認しましょう。

さて、それを見てみましょう...はい、推論に任された場合、ScalaはStringの代わりにJava.lang.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)

最初の2つはパッケージです。実際、StringJava.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

つまり、StringJava.lang.String(以前にインポートされた)のエイリアスです。これは循環参照のように見えますが、 source を確認すると、フルパスで定義されていることがわかります。

type String        = Java.lang.String

次に、理由を尋ねたいかもしれませんさて、私には何の考えもありませんが、そのような重要なクラスを少し作ることだと思いますJVMへの依存度が低くなります。

57