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 

従来のクラスを使用することにより、単純なトレイトの継承と実際の値の自己型を定義して動的に動作を提供することができます。

残念ながら、トレイトのフィールドを再定義する必要があります。私は公正な妥協だと思います。誰かが別のアプローチを知っているかどうか知りたいです。

ありがとう

4

2 に答える 2

2

ユースケースについてはわかりませんが、A機能させたい場合は、次のようにクラスを定義する必要があります。

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

しかし、ケースクラスを使用するための非常に慣用的なアプローチではないと思います。これらは主にデータ コンテナーとして使用され、通常は動作を含みません。(これで達成したいことについて、もう少し情報を伝えることができるかもしれません)

于 2013-05-20T20:11:48.407 に答える