为什么参数处于反位置? [英] Why is parameter in contravariant position?
问题描述
我正在尝试在特征中使用协变类型参数来构造类似的案例类:
I'm trying to use a covariant type parameter inside a trait to construct a case-class like so:
trait MyTrait[+T] {
private case class MyClass(c: T)
}
编译器说:
error: covariant type T occurs in contravariant position in type T of value c
然后我尝试了以下操作,但它也没有用:
I then tried the following but it also didn't work:
trait MyTrait[+T] {
private case class MyClass[U <: T](c: U)
}
这次错误是:
error: covariant type T occurs in contravariant position in type >: Nothing <: T of type U
有人可以解释为什么T在这里处于协变位置并提出解决方案吗?
Thx!
Could somebody explain why the T is in a covariant position here and suggest a solution for this problem? Thx!
推荐答案
这是面向对象编程的基本功能,没有像
This is a fundamental feature of object-oriented programming that doesn't get as much attention as it deserves.
假设您有一个集合 C [+ T]
。 + T
的意思是,如果 U< ;: T
,则 C [U ]< ;: C [T]
。很公平。但是成为子类意味着什么?这意味着每个方法都应该在原始类上起作用。因此,假设您有一个方法 m(t:T)
。这表示您可以使用任何 t
并对其进行处理。但是 C [U]
只能用 U
来做,这可能不是的全部T
!因此,您立即矛盾了您的主张,即 C [U]
是 C [T]
的子类。不是 。 C [T]
可以做的事情, C [U]
不能做的事情
Suppose you have a collection C[+T]
. What the +T
means is that if U <: T
, then C[U] <: C[T]
. Fair enough. But what does it mean to be a subclass? It means that every method should work that worked on the original class. So, suppose you have a method m(t: T)
. This says you can take any t
and do something with it. But C[U]
can only do things with U
, which might not be all of T
! So you have immediately contradicted your claim that C[U]
is a subclass of C[T]
. It's not. There are things you can do with a C[T]
that you can't do with a C[U]
.
现在,如何解决这个问题?
Now, how do you get around this?
一种选择是使类不变(丢弃 +
)。另一个选择是,如果您采用方法参数,则还允许任何超类: m [S> ;: T](s:S)
。现在,如果 T
更改为 U
,则没什么大不了的: T的超类
也是 U
的超类,该方法将起作用。 (但是,您必须更改方法才能处理此类事情。)
One option is to make the class invariant (drop the +
). Another option is that if you take a method parameter, to allow any superclass as well: m[S >: T](s: S)
. Now if T
changes to U
, it's no big deal: a superclass of T
is also a superclass of U
, and the method will work. (However, you then have to change your method to be able to handle such things.)
对于案例类,除非您做到了,否则很难正确地做到这一点。不变的我建议这样做,并将泛型和方差推到其他位置。但是我需要查看更多详细信息,以确保这对您的用例有用。
With a case class, it's even harder to get it right unless you make it invariant. I recommend doing that, and pushing the generics and variance elsewhere. But I'd need to see more details to be sure that this would work for your use case.
这篇关于为什么参数处于反位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!