Scala的.type和Java的.class文字

soc*_*soc 31 java types scala language-design class

我想从语言设计的角度来看为什么Scala已经删除了Java的类文字(例如String.class)并将其替换为classOf[String],但是后来添加了一个"类型文字",其中包含Singletons Singleton.type而不是类似的东西typeOf[Singleton]

huy*_*hjl 31

这是我的理性化:

classOf [T]

classOf被定义Predef为具有此签名的函数:

def classOf[T]: Class[T]
Run Code Online (Sandbox Code Playgroud)

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

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

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

一种:

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

scala> val a: A.type = A
a: A.type = A$@c21a68
Run Code Online (Sandbox Code Playgroud)

我不能指定类似函数返回的类型:

scala> val b = A.type
<console>:1: error: identifier expected but 'type' found.
   val b = A.type
             ^
Run Code Online (Sandbox Code Playgroud)

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

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

scala> val x: A.type1 = 1
x: A.type1 = 1
Run Code Online (Sandbox Code Playgroud)

因此,A.type引用对象的类型并不是一个很大的延伸A.请注意,.type除了引用单例对象的类型之外不会使用它,因此它并不常见.

  • 一个非常有用的`.type`是Scala的`this.type`,对[链接方法调用]特别有用(http://scalada.blogspot.com/2008/02/thistype-for-chaining-method-calls.例如,html). (4认同)

Dan*_*ral 11

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

考虑一下:

class A {
    class B
}

val a: A = new A
val b: a.B = new a.B
Run Code Online (Sandbox Code Playgroud)

这里的要点.是用于表示某个值的成员.它可以是a val,a var,a defobjecta type,也可以是a ,a class或a trait.

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

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