我想要一个通用的向量抽象类/特征来指定某些方法,例如:

trait Vec  
{ 
  def +(v:Vec):Vec 
  def *(d:Double):Vec 
 
  def dot(v:Vec):Double 
  def norm:Double 
} 

我要 Vec2DVec3D延长 Vec :
class Vec2D extends Vec { /* implementation */ } 
class Vec3D extends Vec { /* implementation */ } 

但是,例如,我如何才能做到 Vec2D只能添加到其他 Vec2D而不是 Vec3D ?

现在我只是在实现 Vec2DVec3D没有共同点 Vec祖先,但这会因重复代码而变得乏味。我必须实现所有依赖于这些类的几何类(例如 TrianglePolygonMesh 、...)两次,一次用于 Vec2D再次为 Vec3D .

我看到了 java 实现: javax.vecmath.Vector2djavax.vecmath.Vector3d没有共同的祖先。这是什么原因?有没有办法在scala中克服它?

请您参考如下方法:

您可以使用 self 类型:

trait Vec[T] { self:T => 
  def +(v:T):T 
  def *(d:Double):T 
 
  def dot(v:T):Double 
  def norm:Double 
} 
 
class Vec2D extends Vec[Vec2D] { /* implementation */ } 
class Vec3D extends Vec[Vec3D] { /* implementation */ } 

但是如果两个实现非常相似,您也可以尝试对 Dimension 进行抽象。
sealed trait Dimension 
case object Dim2D extends Dimension 
case object Dim3D extends Dimension 
 
sealed abstract class Vec[D <: Dimension](val data: Array[Double]) {  
 
  def +(v:Vec[D]):Vec[D] = ... 
  def *(d:Double):Vec[D] = ... 
 
  def dot(v:Vec[D]):Double = ... 
  def norm:Double = math.sqrt(data.map(x => x*x).sum) 
} 
 
class Vec2D(x:Double, y:Double) extends Vec[Dim2D.type](Array(x,y)) 
class Vec3D(x:Double, y:Double, z:Double) extends Vec[Dim3D.type](Array(x,y,z)) 

当然,这取决于您希望如何表示数据,以及您是否希望拥有可变或不可变实例。对于“现实世界”应用程序,您应该考虑 http://code.google.com/p/simplex3d/


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!