创建类型别名的实例会导致"需要类类型"错误

Ric*_*ard 11 scala

通过混合ObservableSet使用a 创建了一个新类型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]
  }
}
Run Code Online (Sandbox Code Playgroud)

错误是......

error: class type required but scala.collection.mutable.HashSet[scala.Whatever.X] with scala.collection.mutable.ObservableSet[scala.Whatever.X] found
new  ObservableHashSet[X]
Run Code Online (Sandbox Code Playgroud)

Pao*_*lla 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]
Run Code Online (Sandbox Code Playgroud)

现在,错误确实有意义,让我试着解释原因.

随着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()
Run Code Online (Sandbox Code Playgroud)

所以,问题是:为什么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!
Run Code Online (Sandbox Code Playgroud)

但是如果我们尝试使用不符合结构类型的参数调用test,我们会得到类型不匹配:

scala> test(new HashSet[String])
<console>:13: error: type mismatch;
 found   : scala.collection.mutable.HashSet[String]
 required: ObservableHashSet[String]
Run Code Online (Sandbox Code Playgroud)