2

ノードとその親の間のグラフでタイプの関係を強制しようとしています。child.parents ::= this でコンパイルされない次のものがあります。どんなコメントでも歓迎します

  trait TGraphNode {
    type NodeType <: TGraphNode
    var id = -1
    var parents = List[NodeType]()
    var children = List[TGraphNode]()

    def addChild(child: NodeType) {
      children ::= child
      child.parents ::= this
    }

    override def toString = "node-"+id+"->"+children
  }

申し訳ありません-次回はコンパイルエラーを追加します。私は次のことを達成しようとしています: タイプ F と C の 2 つのノードがあると想像してください - 構造によって C が親として F のみを持つことができるように強制したいのですが、その逆は気にしません。F は C、D.. を子として持つことができます。したがって、特性を実装するクラスで ParentType をオーバーライドできることを把握したいと思います。

class F extends TGraphNode ...
class B extends TGraphNode {
  type ParentType = F
}

ありがとう

4

2 に答える 2

2

エラーメッセージは

error: Type mismatch 
 found   : TGraphNode.this.type (with underlying type TGraphNode)
 required: child.NodeType
             child.parents ::= this

(質問ではそれを省略しないでください)

あなたのコードは、ノードがその親に必要なタイプを変数タイプで選択できることを示していますNodeType。この型は TGraphNode に準拠する必要がありますが、それよりもはるかに制限される場合があります。

そのため、アドインがその親よりも制限されたタイプchildを必要とする可能性があります。コンパイラがそれを拒否するのは適切です。addChildthis

これはエラー メッセージの内容です: You put thisin theparents list of child. thisタイプがありTGraphNodeます。ただし、parentsリストはNodeType子のリスト ( child.NodeType) 型が一致するという保証はありません。

あなたが達成しようとしていることを説明しないと、これ以上コメントできません。


編集後:

これを親として受け入れる子のみを addChild で受け入れることを述べる必要があります。少しトリッキーかもしれませんが、可能な方法は次のとおりです。

def addChild[N](child: TGraphNode{type NodeType = N})
               (implicit thisAsParentOfChild : this.type <:< N) {
  children ::= child
  child.parents ::= thisAsParentOfChild(this)
}

それをしたら、あなたは今できるかもしれません

class F extends TGraphNode {type NodeType = TGraphNode }
class C extends TGraphNode {type NodeType = F }
class X extends TGraphNode {type NodeType = TGraphNode } 

val f = new F
val c = new C
val x = new X

f.addChild(c) // ok 
x.addChild(f) // ok

x.addChild(c) // error: Cannot prove that x.type <:< F

<:< 型の暗黙のパラメーターが何をするかわからない場合は、Scala 2.8 での <:<、<%<、および =:= の意味とは? を見てください。


考え直し、ブルーノートの提案を読むと、書くことaddParentはあなたの文脈よりもはるかに簡単ですaddChild(これが子供と親を逆にする適切な方法だと思います):

def addParent(parent: NodeType) {
  parents ::= parent
  parent.children ::= this
} 
于 2012-11-08T17:31:17.447 に答える
1

私の推測では、タイプNodeTypeとを混同しただけTGraphNodeです。私の理解が正しければ、子は のサブタイプである可能性がありTGraphNodeます。少なくともこれはaddChild関数シグネチャが示すものであり、おそらくより可能性の高い使用例です。したがって、子は型でなければなりませんNodeTypeが、親はより一般的なTGraphNode型を持つことができます。

trait TGraphNode {
  type NodeType <: TGraphNode
  var id = -1
  var children = List[NodeType]()
  var parents = List[TGraphNode]()

  def addChild(child: NodeType) {
    children ::= child
    child.parents ::= this
  }

  override def toString = "node-"+id+"->"+children
}

編集:

わかりました、あなたは本当にそれを逆にしたいのです。上記のバージョンはコンパイルされるため、子と親の定義を逆にするだけで、必要なものを取得できます。

于 2012-11-08T17:32:06.057 に答える