欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

scala actors example

程序员文章站 2022-07-14 13:37:50
...

学习Scala已经有不少时间了,对FP还是不甚了了。现在决定把自己的点滴的进步都记录下来。

 

今天看一个写信并等待回复的场景

Jilen写了一封信给Yision(是我的一个大学同学),现在Jilen把信投递到邮递员Jerry(另外一个大学同学),邮递员把信送给Yision

Yision收到后回复了一封信给Jilen,这封信同样给邮递员Jerry

 

现在看看我们的类型系统


scala actors example

类型系统分成两类对象,人和消息(信件和回复)

先来看看我们的消息系统

 

sealed trait Message {
  val from: Person
  val to: Person
  val content: String
}
case class Letter(val from: Person, val to: Person, val content: String) extends Message
case class Reply(val from: Person, val to: Person, val content: String) extends Message

 

 Letter是一封信,Reply是一封回信(这里继承体系也许不那么合理)

 

再来看看我们的邮递员

 

/**
 * 邮递员
 */
class Postmen(name: String) extends Person(name) {
  def act = {
    loop {
      reactWithin(1000) {
        case x: Message =>
          println("[postmen] a message from %s to %s".format(x.from.name, x.to.name))
          x.to ! x
        case TIMEOUT =>
          println("[postmen] have no message within 1000 ms, i am now going to have a rest")
          exit()
      }
    }
  }
  start()
}

 

 邮递员这里做两件事,

 

  1. 不停查看有没有收到消息,如果有就说有一封从谁写给谁的信需要投递
  2. 如果1000ms内没有任何信件,就下班了
Jerry是这里唯一的邮递员
object Jerry extends Postmen("jerry")
 
 

再看看Jilen(我)是怎么写信的,
Jilen是独一无二的,所以他是一个object
    
/* it is me
*/
object Jilen extends Person("jilen") {
  def act {
    loop {
      react {
        case (toWhom: Person, content: String) =>
          //把信件给邮递员
          Jerry ! Letter(this, toWhom, content)
          receive {
            case Reply(from, to, content) =>
              //收到回复了
              println("[Jilen] a reply from " + from.name + " received, writes \"" + content + "\"")
              exit()
          }
      }
    }
  }

  /**
   * 还不知到这是给谁的信
   */
  class NoReceiver(val content: String) {
    /**
     * 指定信给谁,然后投递给邮递员
     */
    def to(whom: Person) = Jilen ! (whom, content)
  }

  def write(content: String) = {
    new NoReceiver(content)
  }
  start()
}

Jilen有个write方法可以在信纸上写上要说的话,返回一个NoReceiver,可以理解成信封上还没写收信人

  /**
   * 还不知到这是给谁的信
   */
  class NoReceiver(val content: String) {
    /**
     * 指定信给谁,然后投递给邮递员
     */
    def to(whom: Person) = Jilen ! (whom, content)
  }

to 方法填好收信人并告诉自己把信投递出去, 投递之后Jilen开始一直等待回复(下面的receive)

 

 case (toWhom: Person, content: String) =>
          //把信件给邮递员
          Jerry ! Letter(this, toWhom, content)
          receive {
            case Reply(from, to, content) =>
              //收到回复了
              println("[Jilen] a reply from " + from.name + " received, writes \"" + content + "\"")
              exit()

 

Yision同样是一个object,他收到了Jilen的信并回复

 

object Yision extends Person("yision") {
  def act = {
    loop {
      react {
        //收到信并回复
        case Letter(from, to, content) =>
          println("[Yision] receive letter from %s, writes %s".format(from.name, to.name))
          Jerry ! Reply(this, from, "i have received a letter from you, and will reply to you soon")
          exit()
      }
    }
  }
  start()
}

 

等等!整个程序还差一个入口。

 

object App {
  def main(args: Array[String]) {
    Jilen write "hello" to Yision //
  }
}

 main方法只有一行,Jilen写了一封信给Yision,这就像一个导火线点燃了后面Jerry和Yision的所有动作。