类型多态
通常,Scala 中的类型参数被划分为类型。一级类型是值的类型。高阶类型是类型构造函数,例如List
或Map
。类型的类型由它所属的最高类型指示。普通类型是Any
的子类型,协变单参数类型构造函数(如List
)是[+X] =>> Any
的子类型,而Map
类型构造函数是[X, +Y] =>> Any
的子类型。
类型只能按其类型规定的方式使用。Any
的子类型不能应用于类型参数,而[X] =>> Any
的子类型必须应用于类型参数,除非它们传递给相同类型的类型参数。
有时我们希望类型参数可以具有多种类型,例如定义一个适用于任何类型参数的隐式值。现在可以通过一种形式的(子类型)类型多态来实现。类型多态依赖于特殊类型scala.AnyKind
,它可以用作类型的上限。
def f[T <: AnyKind] = ...
f
的实际类型参数可以是任意种类的类型。因此,以下所有内容都是合法的
f[Int]
f[List]
f[Map]
f[[X] =>> String]
我们将具有 AnyKind
上限的类型参数和抽象类型称为任意种类类型。由于任意种类类型的实际种类未知,因此其使用必须受到严格限制:任意种类类型既不能作为值的类型,也不能用类型参数实例化。因此,对任意种类类型唯一可以做的就是将其传递给另一个任意种类类型参数。尽管如此,这足以实现跨种类的一些有趣的泛化,通常通过高级的隐式使用来实现。
(待办事项:插入简洁的示例)
一些技术细节:AnyKind
是一个合成类,就像 Any
一样,但没有任何成员。它不扩展任何其他类。它被声明为 abstract
和 final
,因此它既不能被实例化也不能被扩展。
AnyKind
在 Scala 的子类型系统中扮演着特殊的角色:它是所有其他类型的超类型,无论它们的种类是什么。它也被认为与所有其他类型种类兼容。此外,AnyKind
被视为高阶类型(因此它不能用作值的类型),但同时它没有类型参数(因此它不能被实例化)。
注意:此功能被认为是实验性的,但稳定,并且可以在编译器标志下禁用(即 -Yno-kind-polymorphism
)。