Создание универсального подкласса актера, который также принимает параметр конструктора

У меня есть следующий код, где T — это подкласс актера, который также должен принимать аргумент конструктора:

abstract class AbstractActor(dest: ActorRef) extends Actor {
  //...
}

class ChildActor(dest: ActorRef) extends AbstractActor(dest) {
  //...
}

class ParentActor[T <: AbstractActor : ClassTag] extends Actor {
  val childRef = context.actorOf(Props(classOf[T], destActorRef))
  //...
}

Компилятор выдает ошибку: "Требуется тип класса, но T найден". Я предполагаю, что проблема в том, что можно также определить childActor без параметра конструктора:

class ChildActor extends AbstractActor(dest) {
  //...
}

Итак, я попробовал:

class ParentActor[T <: AbstractActor : ClassTag] extends Actor {

  def createT(dest: ActorRef)(implicit ev: Manifest[T]): ActorRef =
    context.actorOf(Props(ev.runtimeClass, dest))

  val childRef = createT(destActorRef)
  //...
}

Но затем я получаю: «Нет доступных манифестов для T». Любые идеи о том, что я делаю неправильно? Спасибо


person Lasf    schedule 07.07.2014    source источник
comment
Для манифеста, доступного для части T, этот поток может быть полезен: title="почему манифест недоступен в конструкторе"> stackoverflow.com/questions/7294761/   -  person Sudheer Aedama    schedule 08.07.2014


Ответы (1)


При первой попытке ваш код не работает из-за classOf[T]. classOf должен быть задан явный класс, он не может работать с параметром типа, даже если он имеет ClassTag.

Во второй попытке вам потребуется ClassTag для типа T, но тогда createT потребует Manifest. Manifest является подтипом ClassTag, и доступный ClassTag нельзя безопасно преобразовать в Manifest. Однако вы близки, измените требование на [T <: AbstractActor : Manifest], и ваш код должен работать.

person wingedsubmariner    schedule 07.07.2014
comment
Учитывая, что Manifest, по-видимому, исчезнет в какой-то момент в будущем, видите ли какие-либо подводные камни в замене его на ClassTag? Таким образом, у нас было бы (implicit tag: ClassTag[T]), а затем Props(tag.runtimeClass, dest) вместо этого. - person Lasf; 08.07.2014
comment
Похоже, переход на ClassTag — правильный выбор. - person wingedsubmariner; 08.07.2014