Scala的.type和Java的.class文字

2022-09-01 10:46:50

我想知道为什么Scala删除了Java的类文字(例如)并将其替换为,但随后又添加了一个“类型文字”及其单例,而不是类似的东西?String.classclassOf[String]Singleton.typetypeOf[Singleton]


答案 1

这是我的合理化:

类的[T]

classOf在 中定义为具有以下签名的函数:Predef

def classOf[T]: Class[T]

尽管它是由编译器实现的,但可以使用函数语法,而无需在语法方面创建任何特殊处理。因此,这是这里考虑此选项的一个原因。

另一种类似方式意味着每个类都有一个带有字段的伴随对象。所以有两个问题:String.classclass

  1. class是一个关键字,因此这会导致语法需要特殊情况的问题
  2. 如果您只是在没有伴随对象的情况下进行创建,那么能够引用 是很奇怪的,这就像访问伴随对象上的字段一样。class AA.classA

A.类型:

为什么可能会令人困惑。它看起来像一个函数调用,但类型与函数结果不在同一个世界中(函数结果具有类型,但类型本身仅在编译时有意义)。我可以将类型归因于变量:typeOf[A]

scala> val a: A.type = A
a: A.type = A$@c21a68

我无法分配像函数返回的类型:

scala> val b = A.type
<console>:1: error: identifier expected but 'type' found.
   val b = A.type
             ^

另一方面,类型可以是对象的成员:

scala> object A { type type1 = Int }
defined module A

scala> val x: A.type1 = 1
x: A.type1 = 1

因此,参考对象的类型并不大。请注意,除了引用单例对象类型之外,不会使用,因此它实际上并不那么频繁。A.typeA.type


答案 2

实际上,它非常一致。 是 的依赖类型,而 是方法的类型参数。Singleton.typeSingletonclassOf[Class]

请考虑以下情况:

class A {
    class B
}

val a: A = new A
val b: a.B = new a.B

这里的要点是,用于指示作为值的成员的事物。它可以是 a、a、a 或 an,也可以是 a、a 或 a 。.valvardefobjecttypeclasstrait

由于单例对象是一个值,因此是完全有效的。Singleton.type

另一方面,类不是对象,因此没有意义。 不存在(作为值),因此不可能获取其成员。另一方面,它的定义是普通的Scala代码(即使实际的实现是编译器的魔术)。Class.classClassdef classOf[T]: Class[T]