我遇到了一个问题的情况下使用的类和参数化类型与结合的上型。 Scala编译器告诉我,找到键入DefaultEdge
但需要Edge[Type]
。 我试图用类似case DefaultEdge[Type]
但我得到的语法错误。
这里是我的设置。 我有几个对应于不同类型的边缘的情况下的类。 这些类包含的参数化类型V.
object EdgeKind extends Enumeration {
type EdgeKind = Value
val Default, Jump, True, False, DefaultCase, Case, Throw, Return = Value
}
sealed abstract class Edge[V <: VertexLike](val startVertex: V, val endVertex: V, val kind: EdgeKind.EdgeKind)
case class DefaultEdge[V <: VertexLike](override val startVertex: V, override val endVertex: V)
extends Edge[V](startVertex, endVertex, EdgeKind.Default)
case class JumpEdge[V <: VertexLike](//...
然后,我有一个叫做特征GraphLike
定义了几个方法。 唯一有趣的部分应该是这样:
trait GraphLike[V <: VertexLike] {
protected type E <: Edge[V]
}
在之间的另一个特点实现的一些方法GraphLike
特点,被称为GraphLikeWithAdjacencyMatrix
。 当我连线都在一起我有下面的类:
class CFG extends GraphLikeWithAdjacencyMatrix[BasicBlockVertex] {
def dotExport = {
def vertexToString(vertex: BasicBlockVertex) = ""
def edgeToString(edge: E) = edge match {//also tried Edge[BasicBlockVertex] here
case DefaultEdge => error("CFG may not contain default edges.")
case JumpEdge => "jump"
case TrueEdge => "true"
case FalseEdge => "false"
case DefaultCaseEdge => "default"
case CaseEdge => "case"
case ThrowEdge => "throw"
case ReturnEdge => "return"
}
new DOTExport(this, vertexToString, edgeToString)
}
}
这是我遇到的问题。 我得到告诉边缘[BasicBlockVertex]预计,我只能提供DefaultEdge。 在DOTExport的定义是class DOTExport[V <: VertexLike](val graph: GraphLike[V], val vertexToString: V => String, val edgeToString: Edge[V] => String)
所以我的问题是,现在,我怎么能仍然使用情况类边缘类型,使编译器高兴吗? 它必须是在我身边的一些愚蠢的错误。
顺便说一句,本场比赛,代码工作,一旦我说DefaultEdge(x,y)
而不是DefaultCase
等,但随后DOTExport的实例失败,因为边缘[?]是必需的,我通过CFG.E
谢谢!
编辑:实际上的组合E = Edge[V]
在图式流和使用DefaultEdge(_, _)
的工作原理。 这是很不幸的尝试和错误而造成的。 我真的想知道为什么现在的工作。
错误信息:
(fragment of test.scala):25: error:
type mismatch; found :
(Graph.this.E) => java.lang.String
required: (this.Edge[?]) => String
new DOTExport(this, (vertex: V) => vertex.toString, edgeToString)
这是说明我的问题完全编译代码。 同样,我的问题是14行,因为一切正常,当你更换type E <: Edge[V]
与type E = Edge[V]
我不知道为什么。
object EdgeKind {
val Default = 0
val Jump = 1
}
abstract class Edge[V <: VertexLike](val startVertex: V, val endVertex: V, val kind: Int)
case class DefaultEdge[V <: VertexLike](override val startVertex: V, override val endVertex: V) extends Edge[V](startVertex, endVertex, EdgeKind.Default)
case class JumpEdge[V <: VertexLike](override val startVertex: V, override val endVertex: V) extends Edge[V](startVertex, endVertex, EdgeKind.Jump)
trait VertexLike
trait GraphLike[V <: VertexLike] {
protected type E <: Edge[V] // Everything works when E = Edge[V]
}
class DOTExport[V <: VertexLike](val graph: GraphLike[V], val vertexToString: V => String, val edgeToString: Edge[V] => String)
class Graph[V <: VertexLike] extends GraphLike[V] {
def dotExport = {
def edgeToString(edge: E) = edge match {
case DefaultEdge(_, _) => ""
case JumpEdge(_, _) => "jump"
}
new DOTExport(this, (vertex: V) => vertex.toString, edgeToString)
}
}