简体   繁体   English

Scala的.type和Java的.class文字

[英]Scala's .type and Java's .class literal

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

Here is my rationalization: 这是我的理性化:

classOf[T] classOf [T]

classOf is defined in Predef as a function with this signature: classOfPredef定义为具有此签名的函数:

def classOf[T]: Class[T]

Although it's implemented by the compiler, using the function syntax is possible without having to create any special treatment in terms of syntax . 虽然它是由编译器实现的,但是使用函数语法是可能的, 而不必在语法方面创建任何特殊处理 So that's one reason here to consider this option. 所以这是考虑这个选项的一个原因。

The alternative like String.class would imply that each class has a companion object with a field class . String.class这样的替代方案意味着每个类都有一个带有字段class的伴随对象。 So there are two problems: 所以有两个问题:

  1. class is a keyword, so that causes a problem where the syntax would require a special case for it class是一个关键字,因此会导致语法需要特殊情况的问题
  2. if you just create class A without a companion object, it's would be odd to be able to refer to A.class , which would be like accessing the class field on the companion A . 如果您只创建没有伴随对象的class A ,那么能够引用A.class会很奇怪,这就像访问伴侣A上的字段一样。

A.type: 一种:

On why typeOf[A] may be confusing. 关于为什么typeOf[A]可能会令人困惑。 It looks like a function call, but types don't live in the same world as function results (function results have types, but the type itself only makes sense at compile time). 它看起来像一个函数调用,但类型与函数结果不在同一个世界中(函数结果有类型,但类型本身只在编译时才有意义)。 I can ascribe a type to a variable: 我可以将类型归因于变量:

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

I can't assign a type like it's returned by a function: 我不能指定类似函数返回的类型:

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

On the other hand types can be member of a object: 另一方面,类型可以是对象的成员:

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

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

So it is not a big stretch to have A.type refer to the type of object A . 所以让A.type引用对象A的类型并不是一个很大的延伸。 Note that .type aren't used beyond referring to types of singleton objects, so it's not really that frequent. 请注意,除了引用单例对象的类型之外,不会使用.type ,因此它并不常见。

Actually, it is quite consistent. 实际上,这是非常一致的。 Singleton.type is a dependent type of Singleton , while classOf[Class] is a type parameter to a method. Singleton.type是一个依赖型的Singleton ,而classOf[Class]是一种类型的参数的方法。

Consider this: 考虑一下:

class A {
    class B
}

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

The point here is that . 这里的重点是. is used to indicate something that is a member of a value. 用于表示属于值的成员。 It may be a val , a var , a def or an object and it may also be a type , a class or a trait . 它可以是valvardefobject ,也可以是typeclasstrait

Since a singleton object is a value, then Singleton.type is perfectly valid. 由于单例对象是一个值,因此Singleton.type完全有效。

On the other hand, a class is not an object, so Class.class doesn't make sense. 另一方面,类不是对象,因此Class.class没有意义。 Class doesn't exist (as a value), so it is not possible to get a member of it. Class不存在(作为值),因此无法获取它的成员。 On the other hand, it's definition as def classOf[T]: Class[T] is plain Scala code (even if the actual implementation is compiler magic). 另一方面,它定义为def classOf[T]: Class[T]是普通的Scala代码(即使实际的实现是编译魔术)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM