scala 的 actor

先说个技巧 scalac 编译时加上 -print 可以看到产生的中间 java 的代码,这意味着 scalac 某种意义上是将 scala 语法转变成为 java?似乎并不是这样,我看到的似乎还是 scala 代码,但是展开过的(去掉了 scala 特性)。

actor 可以看成某种 grammar sugar,从形式上,它将一个对象接收的消息通过 act 方法封装,并使用 ! 进行消息传递

import scala.actors.Actor

case class MessageTypeA
case class MessageTypeB

class MyActor extends Actor {
  def act = loop {
    react {
      case MessageTypeA => handleMessageTypeA
      case MessageTypeB => handleMessageTypeB
      // ...
    }
  }

  def handleMessageTypeA = {
    // implmentation
  }
  def handleMessageTypeB = {
    // implmentation
  }
}

val actor = new MyActor
actor.start
actor ! MessageTypeA

事实上,这种写法转换成为的 code 还是很复杂的,下面是一些节选出来的片段

package  {
  case class MessageTypeA extends java.lang.Object with ScalaObject with Product with Serializable {
    // ...
  }
  final  object MessageTypeA extends scala.runtime.AbstractFunction0 with ScalaObject with Serializable {
    // ...
  }
  class MyActor extends java.lang.Object with scala.actors.Actor with ScalaObject {
    // ...
    override def !(msg: java.lang.Object): Unit = scala.actors.ReplyReactor$class.!(MyActor.this, msg);
    // ...
  }
}

似乎非常的 ugly… 那么一个自然的问题就是我们为什么需要使用 Actor(除了那些装 b 的语法)?一个简单的例子是实现 observer/listener pattern,在 signal class 里面,我们存有一个 List[Observer],提供基本的 register observer 的方法以及通知 observer 的方法,在 act 里面进行 dispatch 这些消息;在 slot class 里面提供每个 signal 对应的实现,在 act 里面进行 dispatch。好处似乎就是省略了 synchronized 标明的需要同步访问的部分(如添加 observer)。实现的时候一般会为两者定义各自的 trait。Actor 另外提供了 !? 进行同步的消息通讯。

一个比较有意思的东西是 actor 的 composition,即我们在实现 signal 的时候并不是传递消息的参数,而是通过一个 trait(实现了业务逻辑)作用在 observer 上,这样可以将 listener 弄成 generic 的与特定的 traits 绑定后使用。感觉 Actor 还是很诡异的设计….

最后需要说明的是 scala 这套实现并不快,有与 erlang 的比较,似乎慢很多。

——————–
And Abraham said, My son, God will provide himself a lamb for a burnt offering: so they went both of them together.

Advertisements
scala 的 actor

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s