gpt4 book ai didi

scala - 为什么参数处于反位置?

转载 作者:行者123 更新时间:2023-12-03 08:52:09 25 4
gpt4 key购买 nike

我试图在特征中使用协变类型参数来构造一个case类,如下所示:

trait MyTrait[+T] {
private case class MyClass(c: T)
}

编译器说:
error: covariant type T occurs in contravariant position in type T of value c

然后,我尝试了以下操作,但也无法正常工作:
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在这里处于协变位置并提出解决方案吗?
谢谢!

最佳答案

这是面向对象编程的基本功能,没有得到应有的重视。

假设您有一个集合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]做一些事情。

现在,您如何解决这个问题?

一种选择是使类不变(删除+)。另一个选择是,如果采用方法参数,则还允许任何父类(super class):m[S >: T](s: S)。现在,如果T更改为U,没什么大不了的:T的父类(super class)也是U的父类(super class),该方法将起作用。 (但是,您必须更改方法才能处理此类事情。)

对于案例类,除非使之不变,否则很难正确处理。我建议这样做,并将泛型和方差推到其他位置。但是我需要查看更多详细信息,以确保这对您的用例有用。

关于scala - 为什么参数处于反位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9619121/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com