La versión abreviada es que ha creado un alias de tipo para un tipo estructural (que no se puede crear una instancia).
Ésta es una versión simplificada de lo que ha hecho (no funciona):
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]
Ahora, el error no tener algún sentido, y vamos a tratar de explicar por qué. Está definiendo un alias de tipo para algo que no es un tipo concreto (o, como dice el mensaje de error, no es un "tipo de clase"), por lo que no puede crear una instancia de él con new
.
Pero esto (con un paso intermedio en el que hacemos crear un tipo de clase) funciona:
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()
Entonces, la pregunta es: ¿por qué Scala permite crear un alias de tipo que no se puede crear una instancia? Bueno, type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
es un tipo estructural. Aunque, como ha visto en el primer fragmento de código, no puede crear una instancia de este, puede seguir usándolo: p. poner una restricción estructural en un argumento de una función.
Echale un vistazo:
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!
pero si tratamos de llamar a prueba con un argumento que no se ajuste al tipo estructural se obtiene una coincidencia de tipos:
scala> test(new HashSet[String])
<console>:13: error: type mismatch;
found : scala.collection.mutable.HashSet[String]
required: ObservableHashSet[String]
Gracias Paulo. Creo que estaba pensando en "tipo" como una especie de sustitución de macro ... Leeré un poco más sobre tipos estructurales. thx – Richard
@Richard: gracias por la pregunta. Tampoco sabía la respuesta antes de preguntar y experimentar con "tipo" fue instructivo. –