如果泛型类型已经固定,如何使用隐式参数重写泛型方法?
我尝试
def sum[B >: A](implicit num: Numeric[B]): B = ...
在类型 A
已固定为 Int
的子类中重写此方法。
我已经尝试过,
override def sum: Int = ...
但这当然不会覆盖,导致基于运行时动态类型的不同方法解析。
更进一步,
def sum[B >: Int](implicit num: Numeric[B]): Int
does override,而
def sum[B >: Int](implicit num: Numeric[Int]): Int
does not,以及
def sum(implicit num: Numeric[Int]): Int
为什么会这样?至少有可能摆脱多余的绑定B
吗?
我不确定哪些类型和隐式可以省略,哪些必须保留,以便该方法仍然可以覆盖。
I try to override this method
def sum[B >: A](implicit num: Numeric[B]): B = ...
in a subclass where type A
is already fixed to Int
.
I already tried
override def sum: Int = ...
but this doesn't override of course, leading to different method resolution based on the dynamic type at runtime.
Going further,
def sum[B >: Int](implicit num: Numeric[B]): Int
does override, while
def sum[B >: Int](implicit num: Numeric[Int]): Int
does not, as well as
def sum(implicit num: Numeric[Int]): Int
Why is that the case? Is it at leats possible to get rid of the superfluous bound B
?
I'm not sure which types and implicits I can leave out and what has to stay so that the method still overrides.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个问题是重写的方法需要相同数量和类型的类型参数,即使它们没有被使用。例如,
除此之外,还存在健全性问题,因为
Numeric[A]
在A
中是不变的。这意味着只要B
和C
存在,Numeric[B]
和Numeric[C]
之间就没有子类型关系。不同的。想象
Numeric
是具有适当方差的特征,它仍然不起作用;显然,重写方法的签名需要完全相同:我不确定为什么不能扩展重写方法的类型。 编辑:也许原因是与重载的兼容性,如
总结所示,当您重写时,必须保留方法的签名,包括类型参数。就您而言,这是您能做的最好的事情:
The first problem is that overridden methods need the same number and kind of type parameters, even if they are not used. For example,
Beyond this, there's also a problem with soundness since
Numeric[A]
is invariant inA
. This means there is no subtype relationship betweenNumeric[B]
andNumeric[C]
wheneverB
andC
are different.Imagining that
Numeric
were a trait with the proper variance, it still wouldn't work; apparently, the signature of overridden methods needs to be exactly the same:I'm not sure why the types of overridden methods can't be widened. Edit: Perhaps the reason is compatibility with overloading, as in
To summarize, when you override, you must preserve the signature of the method, including the type parameters. In your case, this is about the best you can do:
好的,尝试解释为什么规则必须强制您保留带有隐式参数和方差的签名。
首先,隐式参数仍然是一个参数,它可以显式传递,并且除非它具有单例类型(这不是很有用),否则它的多个不同实例是可能的。
假设我创建
It 看起来像一个正确的
Numeric
。Numeric
文档没有说明应该遵循哪些定律,但ZModulo
并非没有道理。现在,
如果我有
val ints : Summable[Int]
,我当然可以调用ints.Sum(ZModulo(3))
。因此,如果您的类是Summable[Int]
的子类,它必须允许我这样做。因此您无法删除Numeric
参数。其次,假设我带有一个
Numeric[Any]
。不知道如何对数字合理地做到这一点,但规范和编译器无法知道这一点。无论如何,他们也必须接受不合理的实施。因此,让Summable 中的签名允许
ints.sum(MixThemAll)
。所以你的子类也必须允许这样做。因此,让您删除子类中的隐式参数或方差是不合理的。
Ok, trying to explain why the rules must force you to keep the signature with implicit parameter and variance.
First, animplicit argument is still an argument, it can be passed explicitely, and except maybe when it has a singleton type (which would not be very useful), several different instances of it are possible.
Suppose I create
It seems like a proper
Numeric
.Numeric
documentation does not say which laws should be expected, butZModulo
is not unreasonable.Now there is your
If I have
val ints : Summable[Int]
, I am certainly allowed to callints.Sum(ZModulo(3))
. So if your class is to be a subclass ofSummable[Int]
, it must allow me that. So you cannot remove theNumeric
parameter.Second, suppose I come with a
Numeric[Any]
. Not sure how I could do that reasonably for a numeric, but the spec and the compiler can't know that. And anyway, they must accept unreasonable implementations too. So let's haveThe signature in Summable allows
ints.sum(MixThemAll)
. So your subclass must allow that too.So letting you remove either implicit parameter or variance in the subclass would be unsound.