问题描述
我有一个特征,该特征带有一个类型参数,我想说实现此特征的对象也将符合该类型参数(使用泛型,以实现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.
当然,编译器可以在不重复<: B
,self: 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!