有限状态机,也称为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  文档更新时间: 2021-08-30 20:59   作者:Simon