0

「明示的に型付けされた自己参照」の議論を見ています。例は次のように始まります。

abstract class Graph {
  type Edge
  type Node <: NodeIntf
  abstract class NodeIntf {
    def connectWith(node: Node): Edge
  }
  def nodes: List[Node]
  def edges: List[Edge]
  def addNode: Node
}

この例ではself、 のサブクラスを宣言しようとすると、問題が発生します (これを修正するために構成が導入されます) Graph

abstract class DirectedGraph extends Graph {
  ...
  class NodeImpl extends NodeIntf {
    def connectWith(node: Node): Edge = {
      val edge = newEdge(this, node)
      edges = edge :: edges
      edge
    }
  }
  protected def newEdge(from: Node, to: Node): Edge
  ...
}

問題は、関数が最初の引数としてnewEdgea を期待しているのに、内部の呼び出しで a を取得することです。NodeNodeImplconnectWith

なぜこれは自業自得の問題ではないのでしょうか? のサブタイプではなく、抽象クラスまたは特性を最初に宣言Nodeすることで簡単に解決できないでしょうか? それが行われていれば、のサブクラスになる可能性があり、すべて問題ありません。NodeIntfNodeImplNode

4

2 に答える 2

0

はい、いいえと言うでしょう。

はい、すべてのコードを所有している場合は、階層をより適切に設計して、不必要な複雑さを回避できます。

しかし、あなたはあなたが を設計したと仮定しますGraph。しなかったら?そのクラスは、変更できないライブラリまたはレガシー コードから派生している可能性がありますが、それでもそれを利用したいと考えています。

この例は少し不自然かもしれませんが、明示的な型付けthisによって特定のクラスの問題がどのように解決されるかを示すことを目的としています。

于 2013-11-10T19:50:13.503 に答える
0

あなたが示している例は Family Polymorphism に関するもので、研究事例です。

define type variable によって解決された問題Node

abstract class DirectedGraph extends Graph {
  ...
  type Node = NodeImp

  class NodeImpl extends NodeIntf {
  ...

葯の解決策は自己型を定義することです:

class NodeImpl extends NodeIntf {
    self: Node =>

そして、あなたの解決策は次のとおりです。

trait Edge

すべての解決策が受け入れられます。

M.Odersky @ 2006の記事を参照していると思いますが、多くの概念が混在しているため、少し混乱しています。埋め込み型ポリモーフィズム、ファミリ ポリモーフィズム、自己型付けを伴う型変数です。

この記事の私見のアイデアは、一連の分散の可能な解決策を示すことです。

于 2013-11-10T19:52:07.850 に答える