为什么使用上限的子类参数化的不变泛型类型无法符合?

时间:2016-06-12 15:58:37

标签: scala generics inheritance existential-type invariance

假设:

class Invar[T]
trait ExtendsAnyref extends AnyRef
def f(a: Invar[ExtendsAnyref]) = {}

以下是错误的

scala> val x: Function1[Invar[_ <: AnyRef], Unit] = f
<console>:13: error: type mismatch;
 found   : Invar[ExtendsAnyref] => Unit
 required: Invar[_ <: AnyRef] => Unit
       val x: Function1[Invar[_ <: AnyRef], Unit] = f
                                                    ^

为什么?

我理解在Scala中,泛型类型有 默认的非变量子类型。因此,在该示例的上下文中,具有不同类型参数的Invar的实例将永远不会彼此处于子类型关系中。因此,Invar[ExtendsAnyref]无法用作Invar[AnyRef]

但我对_ <: AnyRef的含义感到困惑,我理解为&#34;类型层次结构中AnyRef以下的某些类型。&#34; ExtendsAnyref是类型层次结构中AnyRef下方的某种类型,因此我希望Invar[ExtendsAnyref]符合Invar[_ <: AnyRef]

我理解函数对象在其输入参数类型中是逆变的,但由于我使用Invar[_ <: AnyRef]而不是Invar[AnyRef]我理解,显然不正确,使用上限将具有含义& #34; InvarAnyref或其任何扩展名参数化。&#34;

我错过了什么?

1 个答案:

答案 0 :(得分:1)

写作时

val x: Function1[Invar[_ <: AnyRef], Unit] = ...

这意味着x必须接受任何 Invar[_ <: AnyRef]。也就是说,它必须接受Invar[AnyRef]Invar[String]等。f显然不会:它只接受Invar[ExtendsAnyref]

换句话说,你需要结合最后两段:因为函数在参数类型中是逆变的,因为Function1[Invar[ExtendsAnyref], Unit]符合Function1[Invar[_ <: AnyRef], Unit]你需要Invar[_ <: AnyRef]来符合Invar[ExtendsAnyref],反之亦然。

如果你

  

想要一个使用任何AnyRef子类

进行Invar参数化的函数

这可以写成Function1[Invar[A], Unit] forSome { type A <: AnyRef }。但是,我不相信你可以用这种类型的对象做任何有用的事情,因为1)你能用函数做的唯一事情是将它应用于参数,但2)你不知道是什么这个函数接受的参数。

相关问题