1

鉴于:

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具有不同类型参数的实例永远不会彼此处于子类型关系。所以 anInvar[ExtendsAnyref]不能用作Invar[AnyRef].

_ <: AnyRef但我对我理解的“AnyRef类型层次结构中的 某种类型”的含义感到困惑。ExtendsAnyref是类型层次结构中的某种类型AnyRef,所以我希望Invar[ExtendsAnyref]符合Invar[_ <: AnyRef].

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

我错过了什么?

4

1 回答 1

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) 您不知道什么此函数接受的参数。

于 2016-06-12T19:22:05.747 回答