代码之家  ›  专栏  ›  技术社区  ›  blue-sky

如何在父母和孩子之间发送自定义数据?

  •  0
  • blue-sky  · 技术社区  · 6 年前

    以下代码:

    package playground
    
    import akka.actor.{Actor, ActorRef, ActorSystem, Props, _}
    import akka.stream.ActorMaterializer
    
    case object ReplyMessage
    case object StopMessage
    case object LinRMessage
    case object LinRMessageChild
    
    case class ListData(data : List[String])
    
    class ModelParent(child: ActorRef) extends Actor {
      val logger = com.typesafe.scalalogging.Logger("ModelParent")
    
      def receive = {
    
        case ListData =>
          logger.info("Got reply in Parent")
        case LinRMessage =>
          child ! LinRMessageChild
        case _ => println("Parent got something unexpected.")
      }
    }
    
    class ModelChild extends Actor {
      val logger = com.typesafe.scalalogging.Logger("ModelChild")
    
      def receive = {
        case LinRMessageChild =>
          logger.info("Received LinRMessage")
          //sender ! ReplyMessage
          val l = List("1" , "2" , "3")
          sender ! ListData(l)
        case StopMessage =>
          println("Received Stop Message")
          context.stop(self)
        case _ => println("Child got something unexpected.")
      }
    }
    
    object ModelsDriver {
    
      def main(args: Array[String]): Unit = {
    
        val system = ActorSystem("sys")
        implicit val materializer = ActorMaterializer.create(system)
    
        val modelChild = system.actorOf(Props[ModelChild], name = "modelChild")
        val modelParent = system.actorOf(Props(new ModelParent(modelChild)), name = "modelParent")
    
        modelParent ! LinRMessage
        modelParent ! LinRMessage
        modelParent ! LinRMessage
    
      }
    
    }
    

    打印到控制台:

    22:08:55.807 [sys-akka.actor.default-dispatcher-2] INFO ModelChild - Received LinRMessage
    22:08:55.810 [sys-akka.actor.default-dispatcher-2] INFO ModelChild - Received LinRMessage
    22:08:55.810 [sys-akka.actor.default-dispatcher-2] INFO ModelChild - Received LinRMessage
    Parent got something unexpected.
    Parent got something unexpected.
    Parent got something unexpected.
    

    下面是导致 Parent got something unexpected. 输出:

    case _ => println("Parent got something unexpected.")
    

    我试图将字符串列表从子级返回到类型为的父级参与者:

    case class ListData(data : List[String])
    

    这将填充返回数据:

      val l = List("1" , "2" , "3")
      sender ! ListData(l)
    

    但错误表明我没有正确发送数据。如何在父参与者和子参与者之间发送消息中的数据?

    1 回复  |  直到 6 年前
        1
  •  4
  •   Jack Leow    6 年前

    问题是由于你的父母演员的台词:

    case ListData =>
      logger.info("Got reply in Parent")
    

    通常,您希望模式匹配并提取case类的内容,如下所示:

    case ListData(l: List[String]) =>
      logger.info("Got reply in Parent")
    

    在这里,你可以像 l .

    因为在您的示例中,您并没有对内容进行任何处理,所以您也可以执行以下操作之一:

    case ListData(_) =>
      logger.info("Got reply in Parent")
    

    或者:

    case _: ListData =>
      logger.info("Got reply in Parent")
    
        2
  •  3
  •   Mario Galic    6 年前

    当我们定义一个case类时

    case class Foo(x: Int)
    

    编译器还自动定义相应的伴生单例对象

    object Foo {
      def apply(x: Int): Foo = new Foo(x)
      def unapply(v: Foo): Option[Foo] = ...
    }
    

    这就是功能

    val recieve: Any => String = {
      case Foo    => "I am companion singleton object of Foo"
      case Foo(_) => "I am instance of Foo case class"
    }
    
    recieve(Foo)
    recieve(Foo(42))
    

    输出

    res0: String = I am companion singleton object of Foo
    res1: String = I am instance of Foo case class
    

    我们看到的地方

    case Foo => "I am companion singleton object of Foo"
    

    匹配自动生成的伴生单例对象。

    同样地,

    val recieve: Any => String = {
      case _: Foo.type => "I am companion singleton object of Foo"
      case _: Foo      => "I am instance of Foo case class"
    }
    
    recieve(Foo)
    recieve(Foo(42))
    

    输出

    res0:String=我是Foo的同伴单例对象
    res1:String=我是Foo case类的实例
    

    因为它们是单例对象的类型 Foo Foo.type ,而实例的类型 Foo(42) 也考虑

    val a: Foo = Foo(42)
    val b: Foo.type = Foo 
    

    这个逻辑错误是由于 Any 在里面 Any => Unit 另一方面 Foo => Unit 将在编译时捕获错误

    val recieve: Foo => Unit = {
      case Foo =>  // compiler error: pattern type is incompatible with expected type
    }
    
    推荐文章