检测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;
}
}