我们如何覆盖scala参与者的react构造



检测scala actors中接收到的消息类型的常用方法是通过

loop{
react{
case x: String =>
}
}

然而,我想知道我们如何覆盖react构造的这个实现,以便对接收到的消息进行隐式日志记录。

我正在尝试实现下面提到的一个用例->1。在消息与任何case类匹配之前,我想在控制台/文件上写一条日志语句,显示消息的出现。2.我们可以通过println()/log4j日志来显式地记录这些消息。然而,我想为scala参与者设计一个通用的记录器,它将记录发送或接收的所有消息。

这方面的任何帮助都将是有益的。提前感谢

首先,请注意Scala actors库正在被弃用,取而代之的是Akka。因此,这个答案在很长一段时间内都不会有帮助(尽管其他参与者库将继续提供一段时间——而且如果人们想维护它,它可能永远是开源的)。

无论如何,react方法是在scala.actors.Actor中定义的。只是无法导入它,或者用自己的隐藏它。你自己的什么

这个方法只需要一个PartialFunction[Any,Unit]。所以,你也应该:

def react(pf: PartialFunction[Any,Unit]): Nothing = { /*how?;*/ Actor.react(/*what?*/) }

您实际上只能访问分部函数,并且必须遵从Actor.react才能执行您想要的操作。因此,您需要将pf封装在另一个执行日志记录的PartialFunction中。所以你可以

val qf = new PartialFunction[Any,Unit] {
def isDefinedAt(a: Any) = pf.isDefinedAt(a)
def apply(a: Any): Unit = {
log(a)  // Maybe add more logic to know what a is
pf(a)
}
}

如果您想查看传入并接受检查但未实际使用的消息,也可以使用isDefinedAt做更多的工作。

所以,很明显,我希望/*how?*/是上面定义(创建)qf的,而/*what?*/只是qf

如果你想知道a是否是一个case类,答案是你不能(故意)。case类只是普通Scala特性之上的语法糖;它只是用来帮你打字的。例如,请参阅这个问题。

然而,通过Product的模式匹配并检查它是否有copy方法,您可以非常接近:

case class M(i: Int)
val a: Any = M(5)
scala> a match {
case p: Product if p.getClass.getMethods.exists(_.getName=="copy") => println("Yes")
case _ => println("No")
}
Yes

如果您真的想了解一下,请检查copy是否具有与构造函数相同数量和类型的参数。

//Following is a code for a logReact Method that does the same thing as react but also logs the message received hope this works for you
import scala.actors.Actor;
import scala.actors.Actor._
trait ActorLogging extends Actor {
def logReact(handler: PartialFunction[Any, Unit]): Nothing = {
val handler2: PartialFunction[Any, Unit] = {
case x =>
println("Inside Logs -- with message recieved  -- " + x.toString);
handler.apply(x);
}
super.react(handler2)
}
}
class sumAct extends Actor with ActorLogging {
def act() {
loop {
logReact {
case a: Int =>
println("Inside actor Sum Act Received the message -- " + a)
exit;
}
}
}
}
object ActorLog {
def main(args: Array[String]): Unit = {
var s: sumAct = new sumAct;
s.start();
s ! 1.toInt;
}
}

最新更新