在阅读并尝试从中获取 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
类型的对象,它根据给定的上限约束进行套件。任何详细的解释将不胜感激。
由于绑定Node <: NodeLike
,它正确地失败了。当你做new Edge(this,n)
时,你只是将参数类型作为NodeLike, Node
传递给Edge。但是您的Edge
期望"节点,节点":
class Edge(from: Node, to: Node)
即您正在尝试将NodeLike
传递给Node
(NodeLike 是 Node 的超类型)。这就像将动物传递给期待狗的函数(问题是,如果允许,那么您可以将任何动物(包括猫)传递给一个期待的狗)
解决方法是:
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。
在定义中
def connectWith(n: Node) = new Edge(this, n)
this
有类型 NodeLike
,但是 Edge
的构造函数要求from
是 Node
类型,这是 NodeLike
的一个子类型。您需要自类型注释以确保this
具有所需的Node
类型。