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



给定:

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的含义感到困惑,我理解它的意思是"类型层次结构中低于AnyRef的某种类型"。 ExtendsAnyref是类型层次结构中低于AnyRef的某种类型,因此我希望Invar[ExtendsAnyref]符合Invar[_ <: AnyRef]

我知道函数对象在其输入参数类型中是逆变的,但由于我使用Invar[_ <: AnyRef]而不是Invar[AnyRef]我理解,显然是错误的,使用上限将具有"Invar参数化Anyref或其任何扩展。

我错过了什么?

当你写的时候

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) 你不知道这个函数接受什么参数。

相关内容

  • 没有找到相关文章

最新更新