为什么用上限子类参数化的不变泛型类型不符合?
Why invariant generic type parameterized with subclass of upper bounds fails to conform?
给定:
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
的含义感到困惑,我理解它的意思是 "some type below AnyRef
in the type hierarchy." 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]
,反之则不然。
如果你
want a function that takes Invar parameterized with any subclass of AnyRef
这可以写成Function1[Invar[A], Unit] forSome { type A <: AnyRef }
。但是,我不认为您可以使用这种类型的对象做任何有用的事情,因为 1) 您可以使用函数做的唯一事情就是将它应用于参数,但是 2) 您不知道什么此函数接受的参数。
给定:
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
的含义感到困惑,我理解它的意思是 "some type below AnyRef
in the type hierarchy." 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]
,反之则不然。
如果你
want a function that takes Invar parameterized with any subclass of AnyRef
这可以写成Function1[Invar[A], Unit] forSome { type A <: AnyRef }
。但是,我不认为您可以使用这种类型的对象做任何有用的事情,因为 1) 您可以使用函数做的唯一事情就是将它应用于参数,但是 2) 您不知道什么此函数接受的参数。