为了账号安全,请及时绑定邮箱和手机立即绑定

如何从对象的构造函数中提取此变量的初始化?

如何从对象的构造函数中提取此变量的初始化?

Go
波斯汪 2021-05-11 13:14:57
我正在写我的第一个Go程序,一个SMTP服务器,我认为使用FSM来表示网络协议的状态转换会很不错。我真的很喜欢这个haskell SMTP FSM示例,因此在此之后我对其进行了宽松的建模。我创建了一个简单的FSM类型,该类型将一个过渡表作为其构造函数参数,并具有一个Run方法,该方法接受一个事件,并将在状态表中调用与之匹配的相应处理函数。然后,我有一个“会话”类型,该类型是在处理从其连接传入的SMTP命令之后需要利用FSM的。以下是FSM过渡的外观:type Transition struct {    from    State    event   Event    to      State    handler func() string}然后,在我的Session对象中,我被迫在其构造函数中定义转换表,以便可以访问其用于转换动作的方法:func (s *SmtpSession) NewSession() {    transitions := []Transition{            {Initial, Rset, Initial, sayOk},        {HaveHelo, Rset, HaveHelo, sayOk},        {AnyState, Rset, HaveHelo, resetState},         ...        {Initial, Data, Initial, needHeloFirst},        {HaveHelo, Data, HaveHelo, needMailFromFirst},        {HaveMailFrom, Data, HaveMailFrom, needRcptToFirst},        {HaveRcptTo, Data, HaveData, startData},    }    smtpFsm = StateMachine.NewMachine(transitions)}当所有会话实质上具有相同的FSM时,必须在每个会话中创建此FSM的实例,这似乎很浪费。我宁愿只拥有某种“静态” FSM,可以为其提供一个过渡表,然后Run方法将获取当前状态和一个事件,并返回结果“ action”函数。但是,那是我遇到麻烦的地方。因为所有处理程序函数实际上都是Session对象的方法,所以我必须在Session中定义它。我想不出一种方法,我只能为所有会话定义一次此过渡表,并且仍然可以适当访问我需要的会话处理程序函数。如果我以直接的程序风格编写该程序,那么我将不会遇到任何这些问题。FSM可以直接访问所有处理程序功能。我唯一能想到的就是更改我的FSM,使其不返回函数指针,而是返回一些任意常量,然后Session将这些常量映射到适当的函数:var transitions = []Transition{    {Initial, Rset, Initial, "sayOk"},    {HaveHelo, Rset, HaveHelo, "sayOk"},    {AnyState, Rset, HaveHelo, "resetState"},    ...}var smtpFsm = NewStateMachine(transitions)func (s *Session) handleInput(cmd string) {    event := findEvent(cmd)    handler := findHandler(smtpFsm.Run(s.currentState, event))    handler(cmd)   }func (s *Session) findHandler(handlerKey string) {    switch handlerKey {    case "sayOk":        return sayOk    case "resetState":        return resetState    }}这将解决必须为每个会话重新初始化新的FSM的问题,但同时也会感到有些骇人听闻。有人对我如何避免此问题有任何建议吗?这是一个指向不完整的Session.go的链接,该链接演示了此问题。
查看完整描述

2 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

这整个事情变得这样容易,如果你没有你的处理程序是方法,而而不是把实例作为参数的功能。这大致是同一回事,但是您可以进行某种type State func(Session) State设置,并且可以更轻松地考虑它。


查看完整回答
反对 回复 2021-05-24
  • 2 回答
  • 0 关注
  • 178 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信