检测scala actor中收到的消息类型的常用方法是
loop{
react{
case x: String =>
}
}
但是,我想知道如何覆盖react构造的这个实现,以便我们可以对收到的消息进行隐式记录。
我正在尝试实现下面提到的用例 - > 1.在消息与任何案例类匹配之前,我想在控制台/文件上写一个日志语句,显示消息的出现。 2.我们可以通过println()/ log4j logging显式记录这些消息。但是,我想为scala actor设计一个通用记录器,它将记录发送或接收的所有消息。
这方面的任何帮助都会有所帮助。 提前致谢
答案 0 :(得分:1)
首先,请注意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
是否是一个案例类,答案是你不能(按设计)。案例类只是普通Scala特性之上的语法糖;它只是为了节省你打字。例如,请参阅this question。
但是,您可以通过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
是否与构造函数具有相同数量和类型的参数。
答案 1 :(得分:1)
//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;
}
}