0

在阅读并尝试从中获取 Scala 中可扩展组件背后的所有概念时我仍然无法完全理解为什么这个示例应该具有 self 类型:

abstract class Graph {
  type Node <: NodeLike
    trait NodeLike {    // without self: Node => won't compile
      def connectWith(n: Node) =
    new Edge(this, n)
    }           
    class Edge(from: Node, to: Node)
}

抽象类型Node是的子类型,NodeLike并且是 根据给定的上限约束套件this的类型的对象。NodeLike任何详细的解释将不胜感激。

4

2 回答 2

3

好吧,由于 bound ,它正确地失败了Node <: NodeLike。当您这样做 new Edge(this,n)时,您只是将参数类型传递NodeLike, Node给 Edge。但是您Edge期望“节点,节点”:

class Edge(from: Node, to: Node)

即你试图传递NodeLikeNode(NodeLike 是节点的超级类型)。这就像将 Animal 传递给期望 Dog 的函数(问题是,如果允许,那么您可以将包括 cat 在内的任何 Animal 传递给期望 Dog 的函数)

解决方法是:

abstract class Graph {
    type Node <: NodeLike
    trait NodeLike { // without self: Node => won't compile
      def connectWith(n: Node) =
        new Edge(this, n)
    }
    class Edge(from: NodeLike, to: Node)
  }

或者另一种方式就像您提到的那样,您明确保证您传递的参数是 Node 类型而不是 NodeLike。

于 2013-10-08T19:25:48.413 回答
0

在定义中

def connectWith(n: Node) = new Edge(this, n)

this有类型NodeLike,但是Edge要求的构造函数from是类型Node,它是 的子类型NodeLike。您需要 self 类型注释以确保this具有所需的Node.

于 2013-10-08T19:25:33.537 回答