Scala 为什么可以';我不能在扩展泛型特征的类中调用参数为'this'的方法吗?
我正在写一个trait来描述层次结构中类似节点的对象(如图)。我的工作代码如下:Scala 为什么可以';我不能在扩展泛型特征的类中调用参数为'this'的方法吗?,scala,generics,traits,Scala,Generics,Traits,我正在写一个trait来描述层次结构中类似节点的对象(如图)。我的工作代码如下: trait Hierarchical[T <: Hierarchical[_]] { // The parents will be a list of some arbitrary Hierarchical val parents: List[Hierarchical[_]] = Nil var children: List[Hierarchical[T]] = List() def add
trait Hierarchical[T <: Hierarchical[_]] {
// The parents will be a list of some arbitrary Hierarchical
val parents: List[Hierarchical[_]] = Nil
var children: List[Hierarchical[T]] = List()
def addChild(child: Hierarchical[T]): Unit = {
children ++= List(child)
}
}
abstract class NonRootNode(override val parents: List[Hierarchical[_]])
extends Hierarchical[NonRootNode] {
}
abstract class RootNode extends Hierarchical[NonRootNode] {
final override val parents = Nil
}
然而,在第二次测试中,我发现API有点笨拙。我不需要显式地将子节点添加到根节点,因为我已经指定了子节点的父节点。我想从公共API中删除它,所以我的想法是修改NonRootNode
的构造函数行为,以便为每个父节点调用它。具体来说,我想写:
abstract class NonRootNode(override val parents: List[Hierarchical[_]])
extends Hierarchical[NonRootNode] {
//for each parent, add `this` to its children
parents.map{p=>p.addChild(this)}
}
但是,添加此行时,会出现以下错误:
Error:(19, 29) type mismatch;
found : NonRootNode
required: Hierarchical[_$3]
parents.map{p=>p.addChild(this)}
我不完全确定为什么会出现这个编译器错误。我对层次结构的理解是任何层次结构的,但我可能弄错了。无论如何,我想我已经接近我想要的行为了。我做错了什么?
分层[\u]
并不意味着“任何分层”。它的意思是“某种固定类型的层次结构,这是未知的”
比如说
def foo: Hierarchical[_] = new Hierarchical[Int]
工作:它声明了一个函数,该函数将返回层次结构的一些实现,调用方不知道其确切类型。这很好
另一方面:
def bar(h: Hierarchical[String]) = doStuff(h)
bar(foo)
不起作用:函数bar
需要一个精确类型的参数分层[String]
,传递给它的内容不能保证具有该类型,它的类型参数未知
在您的例子中,.addChild
是一种分层[T]
的方法(其中T
的值对您来说是未知的),并且需要相同类型的参数。但是您要传递给它的是层次化的[NonRootNode]
。这是非法的,因为无法保证NonRootNode
将与(未知的)T相同,当子节点是hierarchy[T]
时,父节点怎么可能是任何hierarchy
?@Jasper-M,因为父节点可以是RootNode
s或NonRootNode
s(或层次结构的任何其他扩展)。孩子们都属于同一类型,因此他们是层次结构的。。有趣——很有意义。有没有一种简单的方法来实现我的行为?我尝试添加一个额外的类型参数,但发现自己处于一种相互递归的情况下,这变得有点麻烦。嗯,我不确定“我的行为”到底是什么意思这里。您的示例不足以推断出这一点,因为根据它判断,层次结构的
完全没有理由被参数化:/所以这可能就是答案——参数化是不必要的。将更新测试并很快报告。而且确实不需要参数化。非常感谢!
def bar(h: Hierarchical[String]) = doStuff(h)
bar(foo)