通过混合ObservableSet
和HashSet
来创建新类型,我有点期望能够替换然后能够使用新类型来创建新实例,如“foo”下面。但是这不能编译,尽管使用该类型的原始长形式似乎很好(如下面的“条形图”所示)。
这只是该语言的一个特征还是我做了一些愚蠢的事情?
package whatever
import collection.mutable._
object Whatever {
type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
class X
def foo {
new ObservableHashSet[X]
}
def bar {
new HashSet[X] with ObservableSet[X]
}
}
错误是..
error: class type required but scala.collection.mutable.HashSet[scala.Whatever.X] with scala.collection.mutable.ObservableSet[scala.Whatever.X] found
new ObservableHashSet[X]
答案 0 :(得分:13)
简要版本是您为结构类型创建了一个类型别名(无法实例化)。
这是你所做的(不起作用)的简化版本:
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!
但如果我们尝试使用不符合结构类型的参数调用test,我们会得到类型不匹配:
scala> test(new HashSet[String])
<console>:13: error: type mismatch;
found : scala.collection.mutable.HashSet[String]
required: ObservableHashSet[String]