Generics 可遍历对象的继承和类型参数

Generics 可遍历对象的继承和类型参数,generics,scala,scala-2.8,scala-collections,Generics,Scala,Scala 2.8,Scala Collections,我正在研究Scala 2.8集合类的源代码。我对scala.collection.Traversable的层次结构有疑问。请看以下声明: package scala.collection trait Traversable[+A] extends TraversableLike[A, Traversable[A]] with GenericTraversableTemplate[A, Traversable] trait Traversable

我正在研究Scala 2.8集合类的源代码。我对scala.collection.Traversable的层次结构有疑问。请看以下声明:

package scala.collection
    trait Traversable[+A]
        extends TraversableLike[A, Traversable[A]] 
        with GenericTraversableTemplate[A, Traversable]

    trait TraversableLike[+A, +Repr]
        extends HasNewBuilder[A, Repr]
        with TraversableOnce[A]

package scala.collection.generic
    trait HasNewBuilder[+A, +Repr]

    trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]]
        extends HasNewBuilder[A, CC[A] @uncheckedVariance]
我想在
GenericTraversableTemplate
中使用
@uncheckedVariance
注释也与此有关?(这似乎是一种潜在的不安全的黑客手段,用来迫使事情运转…)

编辑-在中找到了有关注释的一些有用答案(这是因为
GenericTraversableTemplate
用于方差不同的可变集合和不可变集合)


问题:当您查看层次结构时,您会看到
Traversable
继承了
HasNewBuilder
两次(一次通过
TraversableLike
继承,一次通过
GenericTraversableTemplate
),但类型参数略有不同。这到底是怎么回事?为什么不同的类型参数不会导致错误?

原因是
GenericTraversableTemplate
trait中的
CC
参数。与具有种类
*
(发音为“type”)的普通类型参数不同,此参数具有类型
*=>*
(发音为“type to type”)。为了理解这意味着什么,您首先需要了解一些关于种类的背景知识

考虑以下代码段:

val a: Int = 42
这里我们看到
42
,这是一个值。值具有内在类型。在本例中,我们的值是
42
,类型是
Int
。类型类似于包含许多值的类别。它表示变量
a
可能的值。例如,我们知道
a
不能包含值
“foobar”
,因为该值的类型为
字符串。因此,值有点像第一级抽象,而类型比值高一级

所以问题来了:是什么阻止了我们更进一步?如果值可以有类型,为什么类型上面不能有“某物”?那个“某物”被称为种类。种类是指类型,类型是指值,泛型类别限制了可以描述的类型

让我们看一些具体的例子:

type String
type Int
type List[Int]
这些是类型,它们都有种类
*
。这是最常见的类型(这就是为什么我们称之为“类型”)。实际上,大多数类型都有这种类型。但是,有些人没有:

type List     // note: compile error
这里我们有类型构造函数
列表
,但这次我们“忘记”指定它的类型参数。事实证明,这实际上是一种类型,但却是另一种类型。具体来说,
*=>*
。正如符号所暗示的,这种类型描述了一种类型,它将另一种类型的种类
*
作为参数,从而产生一种新的种类
*
。我们可以在第一个示例中看到这一点,其中我们将
Int
类型(具有kind
*
)传递给
List
类型构造函数(具有kind
*=>*
),生成类型
List[Int]
(具有kind
*

回到
GenericTraversableTemplate
,让我们再次看看声明:

trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]]
请记住,
List
属于
*=>*
(这正是我们需要的
CC
),但是
List[Int]
具有种类
*
,因此编译器拒绝它


对于记录,
GenericTraversableTemplate
本身有一种,具体来说:
(*x(*=>*)=>*)=>*
。这意味着
GenericTraversableTemplate
是一种类型,它将两种类型作为参数——一种是
*
,另一种是
*=>*
——并产生一种类型的
*
。在我们上面的示例中,
GenericTraversableTemplate[String,List]
就是这样一种结果类型,正如我们计算的,它属于
*
(它不需要参数)。

感谢您花时间如此清晰地回答这个问题!我以前听说过“种类”,但直到现在才真正理解它们的含义。
trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]]
type GenericTraversableTemplate[String, List]        // valid!
type GenericTraversableTemplate[String, List[Int]]   // invalid!