在阅读并尝试从this获取Scala中可扩展组件背后的所有概念时,我仍然无法完全理解为什么这个示例应该具有自我类型:
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
类型的对象,它根据给定的上限约束。任何详细的解释将不胜感激。
答案 0 :(得分:3)
由于绑定Node <: NodeLike
,它正确地失败了。当您执行new Edge(this,n)
时,您只需将参数类型作为NodeLike, Node
传递给Edge。但是您的Edge
期望'Node,Node`:
class Edge(from: Node, to: Node)
即。您正尝试将NodeLike
传递给Node
(NodeLike是超级节点类型)。这就像将动物传递给期待狗的功能一样(问题是,如果它被允许,那么你可以将包括猫在内的任何动物传递给期待狗的动物)
解决方法是:
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。
答案 1 :(得分:0)
在定义中
def connectWith(n: Node) = new Edge(this, n)
this
的类型为NodeLike
,但Edge
的构造函数要求from
的类型为Node
,这是NodeLike
的子类型}。您需要自我类型注释,以确保this
具有所需的Node
类型。