我有一个任务:在消息“ userStart”上启动计时器5秒钟,如果用户将在计时器之前发送答案->取消计时器。代码简单易行,问题是如何以FP方式进行编码。据我了解,我应该使用“ val”而不是“ var”。我是FP的新手,所以很高兴有人可以帮助我解决这个问题,或者推荐一些资料来源,在这些资料中我可以找到简单的示例来做这些事情。谢谢!
#include <iostream>
#include <list>
using namespace std;
class Instrument {
public:
virtual void play() {
cout << "..." << endl;;
}
};
class ElectricGuitar: public Instrument {
public:
void play() {
cout << "Djent" << endl;
}
};
class Piano: public Instrument {
public:
void play() {
cout << "Pling" << endl;
}
};
void pointers() {
cout << "Pointers:" << endl;
Instrument *g = new ElectricGuitar();
Instrument *p = new Piano();
g->play(); // Djent
p->play(); // Pling
cout << endl;
}
void references() {
cout << "References:" << endl;
ElectricGuitar g;
Piano p;
Instrument &ig = g;
Instrument &ip = p;
ig.play();
ip.play();
cout << endl;
}
void list_bad() {
cout << "Bad list:" << endl;
list<Instrument> instruments;
instruments.push_back(ElectricGuitar());
instruments.push_back(Piano());
for (auto i: instruments) {
i.play();
}
cout << endl;
}
void list_good() {
cout << "Good list:" << endl;
list<Instrument *> instruments;
instruments.push_back(new ElectricGuitar());
instruments.push_back(new Piano());
for (auto *i: instruments) {
i->play();
}
cout << endl;
}
int main(void) {
pointers();
references();
list_bad();
list_good();
return 0;
}
答案 0 :(得分:2)
以下是使用become
来跟踪接收函数中状态的版本:
class Game extends Actor{
def startTimer(): Cancellable = context.system.scheduler.scheduleOnce(5 seconds, self, "userMissed")
def receive = idleReceive(0)
def idleReceive(actsCount: Int): Actor.Receive = {
case "userStart" => startTimer()
context.become(waitingReceive(actsCount, startTimer()))
sender() ! "do move"
}
def waitingReceive(actsCount: Int, timer: Cancellable): Actor.Receive = {
case "userAct" =>
println("> user made his move")
context.become(idleReceive(actsCount + 1))
timer.cancel()
case "userMissed" =>
println("> user missed his move")
context.become(idleReceive(actsCount))
}
}
需要更多的错误处理,包括在传递“ userAct”消息时计时器触发的竞赛条件。您还需要添加另一条消息来检索actsCount
的值。
答案 1 :(得分:2)
如评论中所述:您的特定用例从本质上讲是全状态的,并且已经封装在Actor
中,从而可以摆脱纯粹的功能范式。
但是,如果您仍然对设计不满意,则可以选择以下几种方法:
有限状态机
Akka提供了一些机制,使Actor的行为类似于FSM。实际上,the example in the documentation看起来很像您的演员。
成为/不成为
演员还具有根据传入的消息change their receive
method的能力。您的计时逻辑可以嵌入到变得&变得不受欢迎的逻辑中。