为什么参数处于反位置? [英] Why is parameter in contravariant position?

查看:80
本文介绍了为什么参数处于反位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在特征中使用协变类型参数来构造类似的案例类:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆