Scala的.type和Java的.class文字

时间:2011-05-25 00:00:46

标签: java class scala types language-design

我从语言设计的角度来看,为什么Scala已经删除了Java的类文字(例如String.class)并将其替换为classOf[String],但后来添加了一个“类型文字”,其单例类似于{{ 1}}而不是Singleton.type

2 个答案:

答案 0 :(得分:30)

这是我的合理化:

<强> classOf [T]

classOfPredef中定义为具有此签名的函数:

def classOf[T]: Class[T]

虽然它是由编译器实现的,但使用函数语法是可能的,而不必在语法方面创建任何特殊处理。所以这是考虑这个选项的一个原因。

String.class这样的替代方案意味着每个类都有一个带有字段class的伴随对象。所以有两个问题:

  1. class是一个关键字,因此会导致语法需要特殊情况的问题
  2. 如果你只是创建class A 而没有一个伴随对象,那么能够引用A.class会很奇怪,就像访问类一样}。
  3. 上的字段

    <强> A.type:

    为什么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.type并不是一件容易的事。请注意,A除了引用单例对象的类型之外不会被使用,因此它并不常见。

答案 1 :(得分:11)

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

考虑一下:

class A {
    class B
}

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

这里的要点是.用于表示属于值的成员。它可以是valvardefobject,也可以是typeclasstrait

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

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