为混合特征的所有 类 构建操作

Build Actions for all classes that mixin a trait

使用 Scala Play 2.3

我有一组模型案例 classes & companions 实现了 特殊特征 - DummyData

trait DummyData[T] {
  def dummy(idx: Long): T

  def dummy(idxs: List[Long]): List[T] = {
    for {idx <- idxs} yield dummy(idx)
  }
}

case class Location(locationIdx: Long)
case class Vehicle(vehicleIdx: Long, mileage: Long)

object Location extends ...
  with DummyData[Location]
{
  def dummy(idx: Long) = {
    SubscriberLocation(idx, "name-" + idx)
  }
}

object Vehicle extends...
  with DummyData[Vehicle]
{
  ...
}

我在控制器中定义了相应的动作:

val dummyIdxs: List[Long] = (1L to 5L).toList

def locationDummy = Action { implicit request =>
  Ok(Json toJson Provider.dummy(dummyIdxs))
}

def vehicleDummy = Action { implicit request =>
  Ok(Json toJson Vehicle.dummy(dummyIdxs))
}
....

每个 Action 中只有一个词是重复代码。

我希望能够制作一个为任何对象提供虚拟数据的操作 class 混合了 DummyData 特性。所以我会定义一个方法 像这样:

def dummyAction[T <: DummyData](modelCompanion: T) = {
  Action { implicit request =>
    Ok(Json toJson modelCompanion.dummy(dummyIdxs))
  }
}

object DummyActionCreator[T] extends (DummyList[T] => TxAction) { 
  def apply(model: DummyList[T]) = TxAction { implicit request =>
    Ok(Json toJson model.dummy(dummyIdxs))
  }
}

然后只需调用

即可进行新操作
def locationDummy = dummyAction[Location]

def locationDummy = dummyAction(Location)

我应该使用什么正确的 Scala 功能来实现这一目标?我需要退后一步,改变特质吗?

我已经尝试了几种变体,但最常出现的错误是 DummyData 需要类型参数。如果我可以修改特征使其不需要类型参数,那将是一个受欢迎的解决方案,但我认为这是必要的

您想要的是一个名为 "existencial types" 的功能。您可以阅读一个体面的解释(这不是一个微不足道的概念,所以我还没有找到一个神奇的博客来立即清楚)here.

以下代码执行您想要的操作并打印“3”

  trait DummyData[T] {
     def dummy(idx: Long): T

     def dummy(idxs: List[Long]): List[T] = {
        for {idx <- idxs} yield dummy(idx)
     }
  }

  object Test extends DummyData[Int]
  {
     override def dummy(idx: Long): Int = 3
  }

  def dummyAction(modelCompanion: DummyData[T] forSome { type T}) =
  {
     modelCompanion.dummy(3)
  }

  def main(args: Array[String]): Unit =
  {
     val dummy3 = dummyAction(Test)
     print(dummy3)
  }

干杯!