Scala 为什么可以';我不能在扩展泛型特征的类中调用参数为'this'的方法吗?

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来描述层次结构中类似节点的对象(如图)。我的工作代码如下:

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)