首页 > 解决方案 > Scala中方法参数的协方差

问题描述

在协方差中,如果参数的类型与泛型类型相同,则方法不允许有参数。这是因为传递类型参数的超类对象变得可行。那是:

class Parent
class Child extends Parent

class Generic[+T] {
   def func(t:T) = ???
}

val x :Generic[Chiild] = new Generic[Child]
val y :Generic[Parent] = x
y.func(new Child)          //This one is illegal; Hence methods are not allowed to have parameters where their type is T.

这是非常直观且易于推理的。对于不允许返回类型的逆变器也是如此。

但是如果我们想让协方差的方法接受参数,可以按照许多博客/文章的方式按照以下方式完成。我在下面给出了完整的例子。

直观地说,如果 'func' 中的 E 是 T 的子类型,那么它是有意义的。这里,如果它是 Apple 或 PinkLady,那么它是有意义的。因为 X 是用 Apple 初始化的。由于同样的原因,在我的第一点中禁止在方法参数中标记协变类型(即:不允许传递水果)。

但是在这里,一切都被接受 理想情况下,当通过 Fruit 时,它应该抛出错误。我真的很困惑为什么水果对象被接受。因此,E 必须是上限(但编译器会出错)。

    class Fruit
    class Apple extends Fruit
    class PinkLady extends Apple

class Generic[+T] {
   def func[E >: T](e:E) = "Hello"     //Function definition        
}

val x = new Generic[Apple]

x.func(new Fruit)
x.func(new Apple)
x.func(new PinkLady)

有人可以帮助我理解。

提前致谢。

标签: scalacovariance

解决方案


的协方差在T这里并不重要 - 没有它(Generic[T])它的工作原理相同。这是因为在将参数传递给函数时,唯一的条件是它必须是超类型T- 所以Any也可以。一切都是 Any,所以你可以通过Apple,“你的名字”,或其他任何东西。


推荐阅读