На самом деле type
ключевое слово в Scala может сделать гораздо больше, чем просто наложить сложный тип на более короткое имя. Он вводит членов типа .
Как вы знаете, у класса могут быть члены поля и члены метода. Ну, Scala также позволяет классу иметь членов типа.
В вашем конкретном случае type
, действительно, вводится псевдоним, который позволяет писать более лаконичный код. Система типов просто заменяет псевдоним реальным типом, когда выполняется проверка типа.
Но вы также можете иметь что-то вроде этого
trait Base {
type T
def method: T
}
class Implementation extends Base {
type T = Int
def method: T = 42
}
Как и любой другой член класса, члены типа также могут быть абстрактными (вы просто не указываете их значение на самом деле) и могут быть переопределены в реализациях.
Члены типа могут рассматриваться как двойные обобщения, так как многие вещи, которые вы можете реализовать с помощью обобщения, могут быть преобразованы в члены абстрактного типа.
Так что да, они могут быть использованы для псевдонимов, но не ограничивайте их только этим, так как они являются мощной функцией системы типов Scala.
Пожалуйста, посмотрите этот отличный ответ для более подробной информации:
Scala: абстрактные типы и дженерики
Мне понравился ответ Роланда Эвальда, так как он описал с очень простым вариантом использования псевдонима типа и для более подробной информации представил очень хороший учебник. Однако, поскольку в этом посте представлен еще один вариант использования с именами членов типа , я хотел бы упомянуть наиболее практичный вариант его использования, который мне очень понравился: (эта часть взята отсюда :)
Абстрактный тип:
T выше говорит, что этот тип, который будет использоваться, пока неизвестен, и в зависимости от конкретного подкласса он будет определен. Лучший способ всегда понять концепции программирования - привести пример. Предположим, у вас есть следующий сценарий:
Здесь вы получите ошибку компиляции, потому что метод eat в классах Cow и Tiger не переопределяет метод eat в классе Animal, потому что их типы параметров различны. Это Трава в классе Корова и Мясо в классе Tiger vs. Food в классе Animal, который является суперклассом, и все подклассы должны соответствовать.
Теперь вернемся к абстракции типов, используя следующую диаграмму и просто добавив абстракцию типов, вы можете определить тип ввода в соответствии с самим подклассом.
Теперь посмотрите на следующие коды:
Компилятор доволен, и мы улучшаем наш дизайн. Мы можем кормить нашу корову коровой. Подходящие корма и компилятор мешают нам кормить коров едой, подходящей для тигра. Но что, если мы хотим сделать различие между типом коровы1 Подходящая еда и корова2 Подходящая еда? Другими словами, в некоторых сценариях было бы очень удобно, если бы путь, по которому мы достигаем тип (конечно, через объект), действительно имел значение. Благодаря расширенным функциям в Scala возможно:
Типы, зависящие от пути: объекты Scala могут иметь типы в качестве членов. Значение типа зависит от пути, который вы используете для доступа к нему. Путь определяется ссылкой на объект (он же экземпляр класса). Для реализации этого сценария необходимо определить класс Grass внутри Cow, т. Е. Cow - это внешний класс, а Grass - внутренний класс. Структура будет такой:
Теперь, если вы попытаетесь скомпилировать этот код:
В строке 4 вы увидите ошибку, поскольку Grass теперь является внутренним классом Cow, поэтому для создания экземпляра Grass нам нужен объект cow, и этот объект cow определяет путь. Таким образом, 2 объекта коровы дают начало двум различным путям. В этом сценарии cow2 хочет есть только пищу, специально созданную для этого. Так:
Теперь все счастливы :-)
источник
Просто пример, чтобы увидеть, как использовать «тип» в качестве псевдонима:
Вышеприведенное определение определяет Action как псевдоним типа процедур (методов), которые принимают пустой список параметров и возвращают Unit.
источник