2

试图找到一种有效且灵活的方法来在 Scala 中存储一系列类类型,以后我可以使用它来启动该类型的新实例:

class Event(

  val name: String,
  val channels: Seq[String],
  val processors: Seq[T] // a sequence of processor classes

)

上面序列中的每个处理器都是一个 Akka Actor 类。我计划在每次收到数据时通过映射处理器来创建一个新的 Actor,如下所示:

event.processors.foreach { processorType =>
  val processor = newProcessor(processorType) // does all the Akka creation stuff
  processor ! Data
}

更新:显然以上是相当正确的,那么我们如何强制它Seq[T]只是处理器类型?所以坚持上课class Calculator extends Processor

我的猜测是我错过了 Scala 的一些陷阱,所以感谢您的帮助。

4

2 回答 2

2

Seq[T]只有存在类型T或类型参数时才有效。

scala> class Event(val seq:Seq[T])
<console>:7: error: not found: type T
       class Event(val seq:Seq[T])
                               ^

要拥有一个类列表,它必须是 Seq[Class[_]]。

假设您提到的处理器是 type Processor。一个较小的说明性示例:

scala>  trait Processor; class P1 extends Processor; class P2 extends Processor

scala> case class Event(val seq:Seq[Class[_ <: Processor]])
defined class Event

scala> Event(List(classOf[P1],classOf[P2]))
res4: Event = Event(List(class P1, class P2))

scala> res4.seq map { _.newInstance }
res6: Seq[Processor] = List(P1@43655bee, P2@337688d3)
于 2012-10-26T20:46:55.833 回答
2

这就是Props为之而生的。using 的优点Props是您可以Processor在运行时将所需的任何参数传递给构造函数,而不是仅限于使用无参数构造函数。

需要注意的一件事Props是它需要一个别名creator参数,所以当你看到Props(new TestActor)那个TestActor时候实际上并没有创建。它是在您传递Propsto时创建的actorOf()

要将Actors 限制为您的子类型,Processor您可以创建Props.

例如:

trait Processor extends Actor

class MyProps(creat: () ⇒ Processor) extends Props(creat)

object MyProps {
  def apply(creator: ⇒ Processor): MyProps = new MyProps(() => creator)
}

你的Event班级会有一个Seq[MyProps]. 这是一个示例测试:

case class Event(      
  name: String,
  channels: Seq[String],
  processors: Seq[MyProps]       
)

class TestActor(bar: String) extends Processor {
  def receive = {
    case msg @ _ => println(bar + " " + msg)
  }
}

object SeqProps extends App {
  override def main(args: Array[String]) {
    val system = ActorSystem()

    val event = new Event("test", Seq("chan1", "chan2", "chan3"), 
      Seq(MyProps(new TestActor("baz")),
          MyProps(new TestActor("barz"))))

    event.processors.foreach { proc =>
      system.actorOf(proc) ! "go!"
    }

    system.shutdown()
  }
}

如果您尝试将非传递ProcessorMyProps()它将在编译时失败。

scala> class NotProcessor extends Actor {
     |   def receive = emptyBehavior
     | }
defined class NotProcessor

scala> MyProps(new NotProcessor)
<console>:15: error: type mismatch;
 found   : NotProcessor
 required: Processor
              MyProps(new NotProcessor)
                      ^
于 2012-10-27T00:37:00.323 回答