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

时间:2015-03-18 00:04:04

标签: scala types playframework-2.0 traits boilerplate

使用Scala Play 2.3

我有一组模型案例类和&实现一个的同伴 特殊特征 - 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 混合在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)

我应该用什么来实现这个?我是否需要退后一步并改变特性?

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

1 个答案:

答案 0 :(得分:1)

你想要的是一个名为&#34;存在类型&#34;的功能。你可以阅读一个不错的解释(这不是一个简单的概念,所以我还没有找到一个神奇的博客,让它立即明确)here

以下代码执行您想要的操作并打印&#34; 3&#34;

  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)
  }

干杯!