方法参数中泛型类型的问题

时间:2017-02-06 16:37:30

标签: scala generics

有人可以解释为什么下面的代码不起作用吗?

scala> abstract class A[T] {}
defined class A

scala> class B {}
defined class B

scala> object C extends A[B] {}
defined object C

scala> def method(arg: A[Any]): Unit = {}
method: (arg: A[Any])Unit

scala> method(C)
<console>:14: error: type mismatch;
 found   : C.type
 required: A[Any]
Note: B <: Any (and C.type <: A[B]), but class A is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
       method(C)

我有一个抽象类,这里名为A,我希望能够将A [AnythingHere]作为参数扩展到方法method。在Java中我会写public void method(A<?> arg) {},但我不知道如何使用Scala,因为没有?

我还尝试将+添加到+T,但在测试并搜索它的功能之后,我在这里找不到它。只是警告消失了

提前致谢

2 个答案:

答案 0 :(得分:3)

代码不起作用,因为如果要在Scala中的 variant contravariant 中使用泛型,则必须明确声明它。否则,将实现Java 不变行为。

默认情况下,Java是不变的。这意味着,如果A < B,那么List[A]List[B]之间就没有任何层次关系。

Scala允许您使用声明泛型类型作为协变或逆变,这意味着

  1. 如果您将通用声明为协变,那么如果A < B,则List[A] < List[B]。为此,您必须使用语法class A[+T]
  2. 声明泛型
  3. 如果您将通用声明为逆变,那么如果A < B,则List[A] > List[B]。为此,您必须使用语法class A[-T]
  4. 声明泛型

答案 1 :(得分:0)

您可能想要使用:def method[T](arg: A[T])

这意味着您不需要更改类定义的方差。