如何修改Scala actor返回List[String]?

问题描述 投票:0回答:1

按照Akka的教程 https:/doc.akka.iodocsakkacurrenttypedguidetutorial_1.html。 我修改了示例代码,以便每3秒向一个akka执行器发送一条消息。

  scheduler.scheduleAtFixedRate(
    initialDelay = Duration(0, TimeUnit.SECONDS),
    interval = Duration(3, TimeUnit.SECONDS))(
    runnable = task)

}

我无法安全地编译将Main中的消息返回从String改为List[String]。所以,我没有用 firstRef ! "printit" ,改成 firstRef ! List("printit") 但这会导致编译器错误。

enter image description here

为了解决这个编译器错误,我对以下内容进行了修改:

class Main(context: ActorContext[String]) extends AbstractBehavior[List[String]](context) {
  override def onMessage(msg: String): Behavior[List[String]] =
def apply(): Behavior[List[String]] =

之前包含的地方。

class Main(context: ActorContext[String]) extends AbstractBehavior[String](context) {
  override def onMessage(msg: String): Behavior[String] =
def apply(): Behavior[String] =

需要改变什么才能返回 List[String] 而不是 StringMain 演员 ?

完整的代码(没有修改)。

 import java.util.concurrent.TimeUnit

    import akka.actor.typed.ActorSystem
    import akka.actor.typed.Behavior
    import akka.actor.typed.scaladsl.AbstractBehavior
    import akka.actor.typed.scaladsl.ActorContext
    import akka.actor.typed.scaladsl.Behaviors
    import map.QTableRow

    import scala.concurrent.ExecutionContext
    import scala.concurrent.duration._
    import ExecutionContext.Implicits.global
    import scala.collection.mutable.ListBuffer

    object PrintMyActorRefActor {
      def apply(): Behavior[String] =
        Behaviors.setup(context => new PrintMyActorRefActor(context))
    }

    class PrintMyActorRefActor(context: ActorContext[String]) extends AbstractBehavior[String](context) {

      override def onMessage(msg: String): Behavior[String] =
        msg match {
          case "printit" =>
            val secondRef = context.spawn(Behaviors.empty[String], "second-actor")
            println(s"Second: $secondRef")
            this
        }
    }

    object Main {
      def apply(): Behavior[String] =
        Behaviors.setup(context => new Main(context))

    }

    class Main(context: ActorContext[String]) extends AbstractBehavior[String](context) {
      override def onMessage(msg: String): Behavior[String] =
        msg match {
          case "getdata" =>

            val firstRef = context.spawn(PrintMyActorRefActor(), "first-actor"+String.valueOf(System.currentTimeMillis()))
            println(s"First: $firstRef")

            firstRef ! "printit"
            this
        }
    }

    object ActorHierarchyExperiments extends App {
      val testSystem = ActorSystem(Main(), "testSystem")
      val scheduler = testSystem.scheduler

      val task = new Runnable { def run() {

        testSystem ! "getdata" }

      }

      scheduler.scheduleAtFixedRate(
        initialDelay = Duration(0, TimeUnit.SECONDS),
        interval = Duration(3, TimeUnit.SECONDS))(
        runnable = task)

    }
scala akka
1个回答
2
投票

firstRef actor reference引用了一个 PrintMyActorRefActor,这是一个 Behavior[ String ],所以要发送任何 List[ String ]对裁判, PrintMyActorRefActor 需要能够接收到它。改变这一点,包括其签名的 recieve 消息,应该可以使该代码段编译。当然,现在,你需要改变一下 PrintMyActorRefActor.onMessage( msg: List[ String ] ): Behavior[ List[ String ] ] 来处理列表而不是单个字符串......

完整的转换代码片段。

import java.util.concurrent.TimeUnit

import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors}
import akka.actor.typed.{ActorSystem, Behavior}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

object PrintMyActorRefActor {
  def apply(): Behavior[List[String]] =
    Behaviors.setup(context => new PrintMyActorRefActor(context))
}

class PrintMyActorRefActor(context: ActorContext[List[String]]) extends AbstractBehavior[List[String]](context) {

  override def onMessage(msg: List[String]): Behavior[List[String]] =
    msg match {
      case "printit" :: xs => // ignores all but the head element
        val secondRef = context.spawn(Behaviors.empty[String], "second-actor")
        println(s"Second: $secondRef")
        this
    }
}

object Main {
  def apply(): Behavior[String] =
    Behaviors.setup(context => new Main(context))

}

class Main(context: ActorContext[String]) extends AbstractBehavior[String](context) {
  override def onMessage(msg: String): Behavior[String] =
    msg match {
      case "getdata" =>

        val firstRef = context.spawn(PrintMyActorRefActor(), "first-actor" + String.valueOf(System.currentTimeMillis()))
        println(s"First: $firstRef")

        firstRef ! List("printit")
        this
    }
}

object ActorHierarchyExperiments extends App {
  val testSystem = ActorSystem(Main(), "testSystem")
  val scheduler = testSystem.scheduler

  val task = new Runnable {
    def run() {
      testSystem ! "getdata"
    }
  }

  scheduler.scheduleAtFixedRate(
    initialDelay = Duration(0, TimeUnit.SECONDS),
    interval = Duration(3, TimeUnit.SECONDS))(
    runnable = task)
}
© www.soinside.com 2019 - 2024. All rights reserved.