在研究Scala时,我遇到了以下片段:
val r = Random
现在,根据我对Alvin Alexander的出色文章(How to create Scala object instances without using the “new” keyword (apply)的了解,您可以创建新的Scala对象实例,而无需使用new关键字,如下所示:
但是,当我查看Random类(Scala 2.12.8)的源代码时,我发现它不是case类,并且伴随对象在其伴随对象中也没有apply方法。
有人可以向我解释为什么创建一个如上所述的随机数是有效的语法,即使它不满足Alvin Alexander帖子中所述的要求吗?
谢谢!
答案 0 :(得分:3)
在这种情况下,Random
是类Random
的单例实例
object Random extends Random
其中
class Random(val self: java.util.Random) extends ... {
...
def this() = this(new java.util.Random())
...
}
因此,它已经是一个值。例如,考虑以下
class Foo(val v: Int)
object Foo extends Foo(42)
Foo.v
输出
res0: Int = 42
请注意Foo
中的Foo.v
已如何引用类Foo
的实例单例值。因此,{p}中的r
val r = Random
只是引用现有的单例值。类似于
val a = 11
val r = a
答案 1 :(得分:3)
简而言之:您不是在创建Random
class的新实例的 ,而是在分配现有实例的 Random
类,也恰好称为字段r
的{{3}}。
听起来class
和object
都名为Random
,这确实令人困惑,但是实际上不可能存在任何混淆,因为在Scala中,类型和术语存在于不同的“世界”及其名称永远不能混用。
请注意,实际上,class
或trait
和object
的名称相同是很普遍的,原因如下:
object
与类或特征具有相同的名称,请和 object
定义为与class
或trait
相同的名称,和 object
在相同的编译单元中定义为class
或trait
,具有相同的名称,然后 < / li>
object
被称为Random
,并且在class
或trait
的内部具有companion module。