浏览 2354 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-09-23
最后修改:2009-09-23
源程序: /** * 《Programming In Scala》第18章 Stateful Objects 例子 */ package org.stairwaybook.simulation //模拟器基类 abstract class Simulation { //模拟动作,为函数 type Action = () => Unit //工作项目,time为动作启动时间,action为动作 case class WorkItem(time: Int, action: Action) //当前时间 private var curtime = 0 //取得当前时间 def currentTime: Int = curtime //工作日程表,例表内项目应按照启动时间的升序排列 private var agenda: List[WorkItem] = List() //向日程表中加入工作项目,ag为目标日程表,item为被插入项目 private def insert(ag: List[WorkItem], item: WorkItem): List[WorkItem] = { //按升序插入 if (ag.isEmpty || item.time < ag.head.time) item :: ag //分割列表,递归调用找到第一个比被插入项目晚的项目 else ag.head :: insert(ag.tail, item) } //向内部日程表中插入指定延时后的工作,delay为延时时间,block为工作函数(by name) def afterDelay(delay: Int)(block: => Unit) { val item = WorkItem(currentTime + delay, () => block) agenda = insert(agenda, item) } //取得日程表中最前面的工作,并将其从日程表中删除,然后执行该工作 private def next() { (agenda: @unchecked) match { case item :: rest => agenda = rest curtime = item.time item.action() } } //执行模拟 def run() { //打印开始时间 afterDelay(0) { println("*** simulation started, time = " + currentTime + " ***") } //执行日程表中所有工作 while (!agenda.isEmpty) next() } } //电路模拟基类 abstract class BasicCircuitSimulation extends Simulation { //反转器延时 def InverterDelay: Int //结合器延时 def AndGateDelay: Int //分离器延时 def OrGateDelay: Int //线路类 class Wire { //线路值(状态) private var sigVal = false //执行动作 private var actions: List[Action] = List() //取得线路值 def getSignal = sigVal //设置线路值,当值有变化就执行所有动作 def setSignal(s: Boolean) = if (s != sigVal) { sigVal = s actions foreach (_ ()) } //加入动作,并且执行一次该动作 def addAction(a: Action) = { actions = a :: actions a() } } //加入反转工作 def inverter(input: Wire, output: Wire) = { def invertAction() { val inputSig = input.getSignal afterDelay(InverterDelay) { output setSignal !inputSig } } //invertAction加入后马上被执行,并且在input的每次状态改变后都会被执行 input addAction invertAction } //加入结合工作 def andGate(a1: Wire, a2: Wire, output: Wire) = { def andAction() = { val a1Sig = a1.getSignal val a2Sig = a2.getSignal afterDelay(AndGateDelay) { output setSignal (a1Sig & a2Sig) } } //addAction加入后马上被执行,并且在a1或a2中的任意一个状态改变后就会被执行 a1 addAction andAction a2 addAction andAction } //加入分离工作 def orGate(o1: Wire, o2: Wire, output: Wire) { def orAction() { val o1Sig = o1.getSignal val o2Sig = o2.getSignal afterDelay(OrGateDelay) { output setSignal (o1Sig | o2Sig) } } //orAction加入后马上被执行,并且在o1或o2中的任意一个状态改变后就会被执行 o1 addAction orAction o2 addAction orAction } //线路监测工作 def probe(name: String, wire: Wire) { def probeAction() { println(name +" "+ currentTime + " newvalue = " + wire.getSignal) } //加入后马上被执行,并且在wire的每次状态改变后都会被执行 wire addAction probeAction } } //扩展电路模拟类 abstract class CircuitSimulation extends BasicCircuitSimulation { //加入半加工作 def halfAdder(a: Wire, b: Wire, s: Wire, c: Wire) { val d, e = new Wire orGate(a, b, d) andGate(a, b, c) inverter(c, e) andGate(d, e, s) } //加入全加工作 def fullAdder(a: Wire, b: Wire, cin: Wire, sum: Wire, cout: Wire) { val s, c1, c2 = new Wire halfAdder(a, cin, s, c1) halfAdder(b, s, sum, c2) orGate(c1, c2, cout) } } //文件主单例对象,作为本文件的主执行程序 object App extends Application { //模拟对象实例 object MySimulation extends CircuitSimulation { def InverterDelay = 1 def AndGateDelay = 3 def OrGateDelay = 5 } //引入模拟对象实例中的所有元素 import MySimulation._ //定义线路 val input1, input2, sum, carry = new Wire //加入监测点 probe("sum", sum) probe("carry", carry) //加入半加 halfAdder(input1, input2, sum, carry) //改变input1的状态 input1 setSignal true //执行模拟 run() //改变input2的状态 input2 setSignal true //执行模拟 run() } 执行结果: sum 0 newvalue = false carry 0 newvalue = false *** simulation started, time = 0 *** sum 8 newvalue = true *** simulation started, time = 8 *** carry 11 newvalue = true sum 15 newvalue = false 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-10-05
我觉得你可以总结下你学习 scala的经验 哪些需要注意 哪些需要避免 读者一般都希望能够通过你写的BLOG获得一定的经验 这样才是交流的目的
|
|
返回顶楼 | |
发表时间:2009-10-05
scanfprintf123 写道 我觉得你可以总结下你学习 scala的经验 哪些需要注意 哪些需要避免 读者一般都希望能够通过你写的BLOG获得一定的经验 这样才是交流的目的
同意你的意见。我们办了一个Scala圈子,主要是提供Scala资料和交流学习经验的,欢迎来看一看 。连接是http://scalagroup.group.iteye.com/。另外我翻译的Scala讲座,挺适合初学者的,连接是http://scalagroup.group.iteye.com/group/blog/480538。 |
|
返回顶楼 | |