2015-03-18 4 views
3

Использования 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)) 
} 
.... 

Все, кроме одного слова каждого действия, является дублирующимся кодом.

Я хочу, чтобы иметь возможность сделать действие, которое предоставляет фиктивные данные для любого класса , который смешивается в черте 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. Если бы я мог изменить признак, чтобы он не нуждался в параметрах типа, это было бы долгожданным решением, но я думаю, что это необходимо

ответ

1

Что вы хотите - это функция, называемая «существующие типы». Вы можете прочитать приличное объяснение (это не тривиальная концепция, поэтому я не нашел волшебный блог, который сразу же очищает) 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) 
    } 

Ура!

 Смежные вопросы

  • Нет связанных вопросов^_^