Ответ 1
Вот моя рационализация:
classOf [Т]
classOf
определяется в Predef
как функция с этой сигнатурой:
def classOf[T]: Class[T]
Хотя он реализован компилятором, использование синтаксиса функции возможно без необходимости создания какой-либо специальной обработки с точки зрения синтаксиса. Так что одна причина здесь, чтобы рассмотреть этот вариант.
Альтернатива, подобная String.class
, подразумевает, что каждый класс имеет объект-компаньон с полем class
. Таким образом, есть две проблемы:
-
class
- это ключевое слово, поэтому возникает проблема, когда для синтаксиса для него требуется специальный случай - Если вы просто создаете
class A
без объекта-компаньона, было бы странно иметь возможность ссылаться наA.class
, что было бы похоже на доступ к полю класса на компаньонеA
.
A.type:
Почему typeOf[A]
может ввести в заблуждение. Это похоже на вызов функции, но типы не живут в том же мире, что и результаты функции (результаты функции имеют типы, но сам тип имеет смысл только во время компиляции). Я могу приписать тип переменной:
scala> val a: A.type = A
a: A.type = [email protected]
Я не могу назначить тип, подобный возвращаемому функцией:
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
. Обратите внимание, что .type
не используются для ссылок на типы одноэлементных объектов, поэтому на самом деле это не так часто.