有限状态机,也称为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
}
}
最后编辑: Simon 文档更新时间: 2024-05-16 21:27 作者:Simon