scala self-type:value不是成员错误

时间:2011-01-23 22:04:36

标签: scala self-type

这是this question的后续内容。

我正在尝试使用自我类型在通用超类中实现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)
                                        ^

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

此外,任何关于自我类型的参考文献都会受到赞赏,因为我认为这些错误是由于我缺乏理解而产生的。

2 个答案:

答案 0 :(得分:9)

要消除所有恶意,您必须指定类型参数VVec的子类。 现在,您可以在任何地方使用V,因为您的特征知道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’s approach编译的方法nasty

答案 1 :(得分: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
}

方法交叉存在于Vec3(或换句话说,位于V),但不存在于Vec[V]