簡體   English   中英

在Scala中引用沒有類型參數的泛型

[英]Refer generic without type parameter in Scala

我在Scala中創建一個樹結構,試圖實現以下類型限制:

  1. 非根節點是三種類型之一 - 時間節點,起始節點或結束節點
  2. 根節點僅具有Time Node類型的子節點
  3. 時間節點僅具有Start Node類型的子節點
  4. “開始節點”僅具有“結束節點”類型的子節點
  5. 終端節點可以具有Start Node或Time Node類型的子節點

這些是我的類型定義:

trait TreeNode[U] {
val children:HashSet[NonRootNode[U]]
  def addChild(c:NonRootNode[U])
}

class NonRootNode[T <: TreeNode[T]] extends TreeNode[T] {
  var passengers:Set[Passenger] = Set()
  val children:HashSet[T] = new HashSet[T]
  def addChild(c:T) = {
    children.add(c)
  }
}

case class RootNode extends TreeNode[TimeNode] {
    val children:HashSet[TimeNode] = new HashSet[TimeNode]
    def addChild(c:TimeNode) = {
      children.add(c)
    }
}

case class TimeNode(time:Int) extends NonRootNode[StartNode] {

}

case class StartNode(l:Option[String]) extends NonRootNode[EndNode] {

}

case class EndNode(l:Option[String]) extends NonRootNode {

}

首先,這是否正確實現了要求1-4? 第二,有沒有辦法在定義中實現要求5? 是否有任何方法可以實現此要求,因為這需要異構集來存儲子引用。

編輯:類型RootNode和EndNode需要一個類似如下的方法:

trait ParentOfTimeNode extends TreeNode{
  //type ChildType = TimeNode
  def addTimeNodes(startTime:Int, maxTime:Int) = {
      for(i <- startTime to maxTime) {
        this.addChild(new TimeNode(i))
      }
    }
}

沒有該行評論,尖叫的線是:

case class EndNode(l:Option[String]) extends NonRootNode with ParentOfTimeNode{ type ChildType = NonRootNode with IntervalMarker }

因為明顯的類型匹配。 在注釋行的情況下,this.addChild會尖叫,因為它是未定義的ChildType綁定的。

我相信我可以實現你的目標,但使用類型成員而不是類型參數。

此外,這意味着我可以將addChild的實現移動到特征中,而不是在子類中重新實現它。

最后,我添加了一個標記特征IntervalMarker來標記EndNode可以作為子節點接受的兩種節點類型。

trait TreeNode {
  type ChildType <: NonRootNode
  val children:HashSet[ChildType] = new HashSet[ChildType]
  def addChild(c:ChildType) = {
    children.add(c)
  }
}

abstract class NonRootNode extends TreeNode {
  var passengers:Set[Passenger] = Set()
}

case object RootNode extends TreeNode { type ChildType = TimeNode }

trait IntervalMarker

case class TimeNode(time:Int) extends NonRootNode with IntervalMarker { type ChildType = StartNode }

case class StartNode(l:Option[String]) extends NonRootNode with IntervalMarker { type ChildType = EndNode }

case class EndNode(l:Option[String]) extends NonRootNode { type ChildType = NonRootNode with IntervalMarker }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM