Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Akka演员-获得演员的状态_Scala_Akka_Actor - Fatal编程技术网

Scala Akka演员-获得演员的状态

Scala Akka演员-获得演员的状态,scala,akka,actor,Scala,Akka,Actor,receive方法在Akka actors中定义了一个actor的行为。我正在寻找一种方法,它可以为我提供参与者在Scala中运行时最好能处理的所有不同消息(及其类型) 直接回答 不幸的是,akka无法提供您所要求的功能。receive方法: PartialFunction无法枚举它可以处理的所有类型。此外,一旦Actor被实例化为ActorRef,您就无法访问底层的receive方法 另一种方法是在Actor实现之外定义接收,然后使用测试特定值: object MyActor { val

receive
方法在Akka actors中定义了一个actor的行为。我正在寻找一种方法,它可以为我提供参与者在Scala中运行时最好能处理的所有不同消息(及其类型)

直接回答

不幸的是,
akka
无法提供您所要求的功能。
receive
方法:

PartialFunction
无法枚举它可以处理的所有类型。此外,一旦
Actor
被实例化为
ActorRef
,您就无法访问底层的
receive
方法

另一种方法是在
Actor
实现之外定义接收,然后使用测试特定值:

object MyActor {
  val myPartial : Receive = {
    //receive functionality
  }
}

class MyActor extends Actor {
  override def receive : Receive = MyActor.myPartial
}

//test if a value can be processed by MyActor

val testValue = 42

val testValueIsDefined = MyActor.myPartial.isDefinedAt(testValue)
间接回答

<>如果你正确地组织你的代码,那么你的问题的基础就变得不必要了。 我发现一个很好的做法是严格声明演员可以接收哪些类型的输入:

sealed trait MyActorInputs

case class Foo(value : Int) extends MyActorInputs
case class Bar(value : String) extends MyActorInputs

object MyActor {
  val processInput : MyActorInput => Unit = ???
}

class MyActor extends Actor {
  override def receive : Receive = {
    case input : MyActorInput => 
      MyActor.processInput(input)
    case unknown => 
      System.error.println(s"MyActor received unknown input: $unknown")
  }
}

这种技术不提供编译器时间检查或严格的保证,但是如果您在所有参与者中都采用这种技术,那么对于更大的项目来说,它会使工作更轻松。它还允许您执行。

这是不可能的。如果需要这样的保证,您可能需要查看akka类型。akka类型无法提供能够处理的消息的“类型”。Scala不是依赖类型的语言,因此类型不是一流的。Akka-typed可以强制执行只有特定的消息才能由特定的“参与者”处理。不,没有。
receive
方法被传递一个
PartialFunction[Any,Unit]
。在akka typed中,您必须指定可以处理的消息类型。还要注意,通过使用
context.been
,参与者可以动态更改其行为(如果参与者没有
context.been
d,则
receive
方法只是默认方法)。正在运行的参与者的行为存储为私有字段(
ActorCell
中的
behaviorStack
)。如果可以访问该字段,则可以获取其头部以获取当前行为,这是一个
部分函数[Any,Unit]
。从中,您可以将消息传递到
isDefinedAt
方法。这样做的最大好处是让您有一个参与者可以及时处理的消息列表,这并不是您想要的,但这没关系,因为除非有重大JVM攻击,您将无法访问该私有字段。您的回答证实,确实无法反映部分函数(receive)的类型。你进一步给出了我将如何编写一个演员程序的见解,我可以对此进行反思。这是方便的信息。然而,我打算放大Akka Scala测试。这些测试将由其他开发人员编程。开发人员还将编写手动测试,我试图自动放大这些测试。为了放大手工编写的测试,我需要访问参与者处理的消息类型。你已经证明了这是不可能的。所以我转向静态分析,注意,仅仅因为一个
PartialFunction[X,Y]
并不能保证处理给定的任何
X
sealed trait MyActorInputs

case class Foo(value : Int) extends MyActorInputs
case class Bar(value : String) extends MyActorInputs

object MyActor {
  val processInput : MyActorInput => Unit = ???
}

class MyActor extends Actor {
  override def receive : Receive = {
    case input : MyActorInput => 
      MyActor.processInput(input)
    case unknown => 
      System.error.println(s"MyActor received unknown input: $unknown")
  }
}