2

ある種の単純なリンクリストを実装したいと考えています。

抽象 No を定義し、フィールドが次にあり、そのタイプは Node です。次に、抽象ノードを継承する他の特定のノードがたくさんあります。

私はこのように書きます:

abstract class Node {
  def next: Node   
}

case class SpecificNode(nxt: Node) extends Node {
  val next = nxt
}

object NullNode extends Node{
  val next = new Exception("no more node")
}

ただし、次のフィールドを変更する必要があることがわかったので、SpecificNode で次のようにします。

case class SpecificNode(nxt: Node) extends Node {
  var next = nxt
}

ただし、next特定のノードのインスタンスのフィールドに割り当てることはできません。たとえばsn.next = ...、コンパイラnext_がノードのメンバーではないと不平を言うためです。

次に、フィールドvarの抽象クラス Node で使用するように変更しました。next

しかし、NullNode を新規作成すると、例外がスローされます (そう定義したため..)

では、ここvarで , ,をどのように使用すればよいでしょうか? これ以上ノードがないことを意味する NullNode をどのように定義すればよいですか?defval

4

1 に答える 1

4

インターフェイスでゲッター/セッターを明示的に定義する必要があります。私たちの場合(構造とアイデアを変更せずに):

trait Node {
    def next: Node
    def next_=(node: Node)
}

// `var next: Node` generates implementations for `def next: Node` and `def next_=(node: Node)`
case class SpecificNode(var next: Node) extends Node

object NullNode extends Node {
    def next = throw new Exception("no more node")
    def next_=(node: Node) { throw new Exception("can't change next on null node") }
}

val n1 = SpecificNode(NullNode)
val n2 = SpecificNode(SpecificNode(NullNode))
val n3: Node = SpecificNode(n1)

// some function to test our structure:
def length(n: Node, prev: Int = 0): Int = if (n == NullNode) prev else length(n.next, prev + 1)

println(length(n3))
n3.next = n2
println(length(n3))

補足: これは変更可能なリンク リストです。標準の scala ライブラリで不変リストがどのように実装されているかを確認することをお勧めします。

于 2012-11-05T06:25:33.890 に答える