有限状态机(FSM)golang的实现

有限状态机,也称为FSM(Finite State Machine),其在任意时刻都处于有限状态集合中的某一状态。当其获得一个输入字符时,将从当前状态转换到另一个状态,或者仍然保持在当前状态。任何一个FSM都可以用状态转换图来描述,图中的节点表示FSM中的一个状态,有向加权边表示输入字符时状态的变化。如果图中不存在与当前状态与输入字符对应的有向边,则FSM将进入“消亡状态(Doom State)”,此后FSM将一直保持“消亡状态”。状态转换图中还有两个特殊状态:状态1称为“起始状态”,表示FSM的初始状态。状态6称为“结束状态”,表示成功识别了所输入的字符序列。

在启动一个FSM时,首先必须将FSM置于“起始状态”,然后输入一系列字符,最终,FSM会到达“结束状态”或者“消亡状态”。

 

说明:

在通常的FSM模型中,一般还存在一个“接受状态”,并且FSM可以从“接受状态”转换到另一个状态,只有在识别最后一个字符后,才会根据最终状态来决定是否接受所输入的字符串。此外,也可以将“其实状态”也作为接受状态,因此空的输入序列也是可以接受的。

FSM的实现

程序设计思路大致如下:

  • 使用状态转换图描述FSM
  • 状态转换图中的结点对应不同的状态对象
  • 每个状态对象通过一个输入字符转换到另一个状态上,或者保持原状态不变。

golang FSM的实现:

下载fsm对应的包
go get github.com/looplab/fsm

代码示例1:

package main

import (
	"fmt"
	"github.com/looplab/fsm"

)

func main() {
	myFsm:=fsm.NewFSM(
		"closed",  //初始化
		fsm.Events{  //事件
			{Name:"开",Src:[]string{"closed"},Dst:"open"},
			{Name:"关",Src:[]string{"open"},Dst:"closed"},
		},
		fsm.Callbacks{},//回调
		)
	fmt.Println("初始化的当前状态为:",myFsm.Current())
	err:=myFsm.Event("开")
	if err!=nil {
		fmt.Println(err)
		return
	}
	fmt.Println("执行了“开”,当前状态为:",myFsm.Current())
	err=myFsm.Event("关")
	if err!=nil {
		fmt.Println(err)
		return
	}
	fmt.Println("执行了“关”,当前状态为:",myFsm.Current())
	fmt.Println()
}

代码示例2:

package main

import (
	"fmt"
	"github.com/looplab/fsm"
)

type Door struct {
	Name string
	FSM *fsm.FSM
}
func NewDoor(name string)*Door  {
	d:=&Door{
		Name:name,
	}
	d.FSM=fsm.NewFSM(
		"closed",
		fsm.Events{
			{Name:"开",Src:[]string{"closed"},Dst:"open"},
			{Name:"关",Src:[]string{"open"},Dst:"closed"},
		},
		fsm.Callbacks{
			"enter_state": func(event *fsm.Event) {
				fmt.Printf("the door : %s is %s\n",d.Name,event.Dst)
			},
		},
		)
	return d

}
func main() {
	door:=NewDoor("宣武门")
	err:=door.FSM.Event("开")
	if err!=nil {
		fmt.Println(err)
		return
	}
	err=door.FSM.Event("关")
	if err!=nil {
		fmt.Println(err)
		return
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42117918/article/details/90764268