1

情况:

trait Operation {
def something: Double 
}

trait OperationPlus { this: A =>
override def something: Double = x + y
}
trait OperationMinus { this: A =>
    override def something: Double = x - y
}

case class A(x: Double, y: Double) { this:  Operation =>
}

val a = new A(1.0, 2.0) with OperationPlus
  println(a.something)

错误:

class A cannot be instantiated because it does not conform to its self-type A with Operation

另外,我无法实例化 A。

我尝试了多种不同的方法,但没有一个提供我正在寻找的东西。我不想使用案例类继承,或者放弃案例类,理想情况下,特质/自我类型/其他东西应该可以解决问题。有任何想法吗?

更新 首选解决方案

 trait Operation { this: A =>
 def something: Double 
 }

 trait OperationPlus extends Operation { this: A =>
   override def something: Double = x + y
 }
 trait OperationMinus extends Operation { this: A =>
     override def something: Double = x - y
 }

 abstract case class A(val x: Double, val y: Double) extends Operation

 val a = new A(1.0, 2.0) with OperationPlus
 println(a.something)

 val b = new A(1.0, 2.0) with OperationMinus
 println(b.something)

可能的解决方案1:

trait Operation {
  def x:Double 
  def y:Double
  def something: Double 
}

trait OperationPlus extends Operation {
  override def something: Double = x + y
}
trait OperationMinus extends Operation {
      override def something: Double = x - y
}

abstract case class A(val x: Double, val y: Double) extends Operation 

通过使用常规类,简单的 trait 继承和实际值中的自类型可以定义它并动态提供行为。

不幸的是,我必须重新定义特征中的字段。我想这是一个公平的妥协。有兴趣知道是否有人知道另一种方法。

谢谢

4

2 回答 2

2

不确定你的用例,但A如果你想让它工作,你需要像这样定义类:

abstract case class A(x: Double, y: Double) extends Operation

但我不认为用例类的惯用方法。它们主要用作数据容器,通常不包含任何行为。(也许你可以告诉一些关于你想用这个实现的事情的更多信息)

于 2013-05-20T20:11:48.407 回答
2

首先,你应该有:

trait OperationPlus extends Operation
trait OperationMinus extends Operation

其次,您不能定义A为案例类,因为它会自动定义apply伴随对象上的方法,在哪里new A调用(带有参数)。由于错误的自我类型(您看到的错误),此调用失败。

删除case. 如果您需要模式匹配,请自己定义一个提取器(实现unapply):

class A(val x: Double, val y: Double) { this: Operation => }

object A {
  def unapply(v: A) = Some((v.x, v.y))
}
于 2013-05-20T20:21:30.683 回答