Scala String vs java.lang.String - 类型推断

Lui*_*hys 40 string types scala type-inference

在REPL中,我定义了一个函数.请注意返回类型.

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

如果我将返回类型指定为String

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

为什么不同?我也可以将返回类型指定为List [Any],所以我猜String只是java.lang.String的包装器超类型.这有任何实际意义,还是我可以安全地不指定退货类型?

Dan*_*ral 56

这个问题问得好!首先,我向您保证,您可以安全地指定退货类型.

现在,让我们看看它......是的,当推断时,Scala推断java.lang.String,而不仅仅是String.因此,如果你在ScalaDoc中查找"String" ,你将找不到任何东西,这似乎表明它不是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)
Run Code Online (Sandbox Code Playgroud)

前两个是包 - 实际上,String可以找到java.lang!那是吗?让我们通过实例化该包中的其他内容来检查:

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

scala> val s: String = new String
s: String = ""
Run Code Online (Sandbox Code Playgroud)

所以,这似乎不是它.现在,它不能在scala包内,或者在查找ScalaDoc时会发现它.所以让我们看看里面scala.Predef,它就在那里!

type String = String
Run Code Online (Sandbox Code Playgroud)

这意味着String是一个别名java.lang.String(这是以前的进口).这看起来像一个循环引用,但是如果你检查源代码,你会看到它是用完整路径定义的:

type String        = java.lang.String
Run Code Online (Sandbox Code Playgroud)

接下来,您可能想问为什么?好吧,我什么都不知道,但我怀疑是要让这样一个重要的类稍微依赖于JVM.