在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的包装器超类型。这有任何实际意义,还是我可以安全地不指定返回类型?
答案 0 :(得分:54)
这是一个非常好的问题!首先,我向您保证,您可以安全地指定退货类型。
现在,让我们看一下......是的,当离开推理时,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)
前两个是包 - 事实上,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
的别名(之前已导入)。这看起来像是一个循环引用,但如果你检查source,你会看到它是用完整路径定义的:
type String = java.lang.String
接下来,您可能想问为什么?嗯,我不知道,但我怀疑是要让这样一个重要的类稍微依赖于JVM。