我目前正在阅读LYAE
,并且我试图了解为什么gen_fsm
状态方法必须根据source完全返回任何内容
{reply, Reply, NextStateName, NewStateData}
{reply, Reply, NextStateName, NewStateData, Timeout}
{reply, Reply, NextStateName, NewStateData, hibernate}
{next_state, NextStateName, NewStateData}
{next_state, NextStateName, NewStateData, Timeout}
{next_state, NextStateName, NewStateData, hibernate}
{stop, Reason, Reply, NewStateData}
{stop, Reason, NewStateData}
如果我有3种状态方法:a
,b
和c
,有人可以向我解释,状态机的定义如下:
a()->
receive
something -> b();
_ -> error(err)
end.
b()->
receive
somethingelse-> c();
_ ->
end.
为什么我需要下一个状态方法的返回结果?
someMethod()->
receive
_ ->
{next_state, NextStateName, NewStateData}=someNextMethod(),
//why would i place code here? What could i possibly do with the above tuple ?
end.
我不明白为什么我要在调用代码后再调用下一个状态方法?所有调用都是递归的,所以除了初始状态(在fsm结束或抛出之后我实际上可以执行某些操作)之外,为什么还要在其他状态下放置代码?
答案 0 :(得分:3)
您是正确的,不需要返回值,并且必须对将要在接收语句上等待的某些函数进行递归调用:有必要使事情发展(由于变量的不变性)并做出反应到一条新消息。
重点是您的示例是一个模块状态机,而当您使用gen_fsm行为时,至少有两个模块在起作用:
每个模块的角色都非常不同。
简而言之,gen_fsm是一个简单的递归循环,等待“事件”消息,这些消息至少维护State_name变量。它使用存储在回调模块中的辅助函数来描述其行为。与您所说的相距不远,但受到通用模块带来的限制-以及集成到OTP和经过验证的代码的优势。
答案 1 :(得分:2)
{next_state, NextStateName, NewStateData}=someNextMethod(),
//why would i place code here? What could i possibly do with the above tuple ?
例如:
{next_state, NextStateName, NewStateData}=someNextMethod(),
{next_state, NextStateName, NewStateData + 1}
或者:
{next_state, NextStateName, NewStateData}=someNextMethod(),
ModifiedStateData = do_calculation(NewStateData),
{next_state, NextStateName, ModifiedStateData}