如何让Scala正确地解析这些抽象类型
如何让Scala正确地解析这些抽象类型
我在构建这个类层次结构时遇到了困难。我有一个抽象数据包"Vertex"和一个操作Vertex实例的抽象类"VertexShader"。实际上,从VertexShader派生的类操作特定派生类的Vertex。这很像经典的Animal类示例,它有一个"def eat(f : Food)"方法,但是它的子类只能吃特定类型的食物。
问题在于派生的Vertex类应该提供一个"+"函数,可以对顶点进行操作,并且我需要将此操作的结果传递给VertexShader。问题在于,即使类型通过推断正确解析,系统也不允许我将"+"操作的结果传递给VertexShader对象。
非常欢迎任何关于如何重新设计以避免类型问题的建议。
抽象接口类型:
trait Vertex {
type V <: Vertex
def position: Float
def + (v: V): V
}
派生的顶点着色器类将使用特定派生类的顶点进行着色:
trait VertexShader {
type V <: Vertex
def shade(v: V): Float
}
具体的实现示例:
class MyVertex(p: Float, c: Float) extends Vertex {
type V = MyVertex
val position: Float = p
val color: Float = p * 2.0f
def + (v: MyVertex): MyVertex = new MyVertex(position + v.position, color + v.color)
}
class MyVertexShader extends VertexShader {
type V = MyVertex
def shade(v: MyVertex): Float = v.position + v.color
}
对象Bootstrap:
def main(args: Array[String]) {
// 顶点和顶点着色器,假设具体类类型在运行时从其他抽象对象接口中获取
val mVShader: VertexShader = new MyVertexShader
val mV0: Vertex = new MyVertex(1.0f, 9.0f)
val shadeValue = mVShader.shade(mV0 + mV0)
}
问题的出现原因是类型注解丢失了信息。在代码中,通过声明val mVShader : VertexShader = new MyVertexShader
,仅仅指定了它是一个VertexShader类型,但是为了将MyVertex传递给它的shade方法,需要更加具体地指定类型。val mVShader : VertexShader {type V = MyVertex} = new MyVertexShader
可以实现这个目的。
最简单和简洁的解决方法是移除类型注解:
val mVShader = new MyVertexShader val mV0 = new MyVertex(1.0f, 9.0f)
对于你的评论的回答:
如果有这样的代码:
trait Mesh { trait T <: Vertex def getVertex: T }
和
class AMesh extends Mesh { ... }
你可以通过AMesh#T
获得AMesh的具体类型T
,对于特定的AMash对象,可以使用val amesh: AMesh = ...
... amesh.T ...,但这是一个棘手的问题,不一定总能正常工作,或者需要使用dependent method types。
是的,这将解决这个示例问题,但在实际情况下,假设我有一个抽象类型为Mesh的引用(val),它有一个函数"def generateVertex : Vertex",当然它返回一个特定类型T < Vertex的顶点。我能从这个Mesh对象获取这个类型信息吗?例如,如果类Mesh声明了"type V < Vertex",我可以说Mesh.V吗?