Ответ 1
Краткая версия состоит в том, что вы создали псевдоним типа для структурного типа (который вы не можете создать).
Это упрощенная версия того, что вы сделали (не работает):
scala> import collection.mutable._
import collection.mutable._
scala> type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
defined type alias ObservableHashSet
scala> new ObservableHashSet[String]
<console>:12: error: class type required but scala.collection.mutable.HashSet[String] with scala.collection.mutable.ObservableSet[String] found new ObservableHashSet[String]
Теперь ошибка имеет смысл, и позвольте мне попытаться объяснить, почему.
С помощью type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
вы определяете псевдоним типа для того, что не является конкретным типом (или, как сказано в сообщении об ошибке, а не "тип класса" ), поэтому вы не можете создать экземпляр его с помощью new
.
Но это (с промежуточным шагом, на котором мы создаем тип класса) работает:
scala> class ObservableHashSet[T] extends HashSet[T] with ObservableSet[T]
defined class ObservableHashSet
scala> type obs[T] = ObservableHashSet[T]
defined type alias obs
scala> new obs[String]
res1: ObservableHashSet[String] = Set()
Итак, возникает вопрос: почему scala позволяет создать псевдоним типа, который вы не можете создать?
Хорошо, type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
является структурным типом. Хотя, как вы видели в первом фрагменте кода, вы не можете создать его экземпляр, вы все равно можете его использовать: например. поставить структурное ограничение на аргумент функции.
Посмотрите:
scala> type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
defined type alias ObservableHashSet
scala> def test(obsHashSet: ObservableHashSet[String]) : String = {"bingo!"}
test: (obsHashSet: ObservableHashSet[String])String
scala> test(new HashSet[String] with ObservableSet[String])
res4: String = bingo!
но если мы попытаемся вызвать тест с аргументом, который не соответствует структурному типу, мы получим несоответствие типа:
scala> test(new HashSet[String])
<console>:13: error: type mismatch;
found : scala.collection.mutable.HashSet[String]
required: ObservableHashSet[String]