Scala:非法继承;自类型Y不符合X的自类型SELF [英] Scala: illegal inheritance; self-type Y does not conform to X's selftype SELF

查看:163
本文介绍了Scala:非法继承;自类型Y不符合X的自类型SELF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个特征,该特征带有一个类型参数,我想说实现此特征的对象也将符合该类型参数(使用泛型,以实现Java的兼容性)

I have a trait, which takes a type parameter, and I want to say that the objects that implements this trait will also conform to this type parameter (using generics, for Java's compatibility)

以下代码:

trait HandleOwner[SELF <: HandleOwner[SELF]] {
self : SELF =>
    // ...
    def handle: Handle[SELF]
}

trait Common[SELF <: Common[SELF]]  extends HandleOwner[SELF] {
    // ...
}

给我以下错误:

illegal inheritance;  self-type test.Common[SELF] does not conform to
test.HandleOwner[SELF]'s selftype SELF

如果我将通用"更改为:

If I change Common to:

trait Common[SELF <: Common[SELF]]  extends HandleOwner[SELF] {
self : SELF =>
    // ...
}

然后错误消失了.

为什么我必须在每个非具体类型中重复相同的声明.如果我有一个基类,并说"extends Comparable",则不必在每个派生类型中重复"extends Comparable",只要 concrete classes 实现compareTo方法即可.我认为这里应该是同一回事.我只是说扩展HandleOwner 的类型也将是,并且编译器应只接受它,并将其考虑在内,而不需要每个非具体的子类型再次重复相同的事情.

Why is it that I have to repeat the same declaration in every non-concrete type. If I would have a base class, and say "extends Comparable", I don't have to repeat "extends Comparable" in every derived type, as long as the concrete classes implement the compareTo method. I think it should be the same thing here. I am just saying that a type extending HandleOwner will be also a SELF, and the compiler should just accept it, and take it into consideration while not requiring every non-concrete subtype to repeat the same thing again.

这样做是为了避免必须使用类转换,但是我将在字面上扩展该特性的每个类,而且我不认为我必须重复数百次甚至数千次此声明!

A am doing this to avoid having to use a class-cast, but I will be literally extending every class from this trait, and I don't see that I should have to repeat this declarations hundreds or even thousands of times!

推荐答案

自类型更类似于泛型约束而不是继承.对于class C[A <: B],必须始终在子类class D[A <: B] extends C[A]中重复该约束.必须重复约束,直到满足约束,即直到您选择确实满足<: B的实际参数类型为止.相同的自我类型.编写self: A =>不会使您的类型扩展A.它确保了在最终实例化它之前,最终将必须将它与A混合在一起.

Self type is more akin to generic constraint than to inheritance. With class C[A <: B], the constraint must be repeated all along in subclasses : class D[A <: B] extends C[A]. The constraint must be repeated until it is satisfied, that is until you have chosen an actual parameter type which indeed satisfies <: B. Same for the self type. Writing self: A => does not makes your type extend A. It ensures that it will ultimately have to be mixed in with A before it is actually instantiated.

相反,当扩展Comparable时,您已将类设为Comparable,而不是为以后设置了约束.但是,您需要实施compareTo的事实仍然必须与abstract一起重复,直到您真正实施它为止.

On the opposite, when you extend Comparable, you have made your class a Comparable, not put a constraint for later on. But the fact that you need to implement compareTo has still to be repeated all along with abstract until you actually implement it.

当然,编译器可以在不重复<: Bself: A =>abstract的情况下执行此操作,因此信息可用.这是语言设计师的选择.至少,必须重复self: A =>与其他地方的规则没有什么不同.

Certainly the compiler could do without repeating <: B, self: A =>, and abstract, the info is available to it. This is language designer choice. At least, having to repeat self: A => is not different from the rules everywhere else.

这篇关于Scala:非法继承;自类型Y不符合X的自类型SELF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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