0

这是对这个问题的跟进。

我正在尝试使用自类型使用通用超类在 scala 中实现向量:

trait Vec[V] { self:V =>
  def /(d:Double):Vec[V] 
  def dot(v:V):Double

  def norm:Double = math.sqrt(this dot this)
  def normalize = self / norm
}

这是一个 3D 向量的实现:

class Vec3(val x:Double, val y:Double, val z:Double) extends Vec[Vec3]
{
  def /(d:Double) = new Vec3(x / d, y / d, z / d)
  def dot(v:Vec3) = x * v.x + y * v.y + z * v.z 
  def cross(v:Vec3):Vec3 = 
  {
      val (a, b, c) = (v.x, v.y, v.z)
      new Vec3(c * y - b * z, a * z - c * x, b * x - a * y)
  }

  def perpTo(v:Vec3) = (this.normalize).cross(v.normalize)
}

不幸的是,这不能编译:

Vec3.scala:10: error: value cross is not a member of Vec[Vec3]
  def perpTo(v:Vec3) = (this.normalize).cross(v.normalize)
                                        ^

出了什么问题,我该如何解决?

此外,任何关于自我类型的参考都将不胜感激,因为我认为这些错误是由于我缺乏理解而出现的。

4

2 回答 2

9

为了摆脱所有的麻烦,您必须指定类型参数VVec. 现在您可以在V任何地方使用,因为您的 trait 知道V继承所有Vec[V]方法。

trait Vec[V <: Vec[V]] { self: V =>
  def -(v:V): V
  def /(d:Double): V
  def dot(v:V): Double

  def norm:Double = math.sqrt(this dot this)
  def normalize: V = self / norm
  def dist(v: V) = (self - v).norm
  def nasty(v: V) = (self / norm).norm
}

请注意使用Easy Angel 的方法nasty无法编译的方法。

于 2011-01-23T23:10:01.033 回答
3

我认为,该方法/应该Vec返回V而不是Vec[V]

trait Vec[V] { self:V =>
  def /(d:Double): V
  def dot(v:V):Double

  def norm:Double = math.sqrt(this dot this)
  def normalize = self / norm
}

方法 cross 存在于Vec3(或换句话说存在于V)但不存在于Vec[V]

于 2011-01-23T22:12:30.973 回答