• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

go-FSM(有限状态机)初体验

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

FSM有限状态机

/**
* @Author: wsp
* @Time    : 2018/4/11 16:45
* @Description:
 */
package fsmStrudy

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

type Door struct {
    To  string
    FSM *fsm.FSM
}

func NewDoor(to string) *Door {
    d := &Door{
        To: to,
    }

    d.FSM = fsm.NewFSM(
        "closed",
        fsm.Events{
            {Name: "open", Src: []string{"closed"}, Dst: "open"},
            {Name: "close", Src: []string{"open"}, Dst: "closed"},
        },
        fsm.Callbacks{
            "enter_state": func(e *fsm.Event) { d.enterState(e) },
        },
    )

    return d
}

func (d *Door) enterState(e *fsm.Event) {
    fmt.Printf("The door to %s is %s\n", d.To, e.Dst)
}
func FsmStudy() {
   // 创建door对象 door :
= NewDoor("heaven")    // 状态改变,此时对应fsm.Events中的Name:open状态,此时状态由closed转变为open
// 然后调用回调函数 d.enterState(e),打印出当时状态 err :
= door.FSM.Event("open") if err != nil { fmt.Println(err) } err = door.FSM.Event("close") if err != nil { fmt.Println(err) } }

然后进行深一层次,丰富状态机转变时对应回调函数的调用及执行,类似java中拦截器,状态转变之前执行对应before_xxx的函数,

执行完后执行leave_state的函数,代码:

/**
* @Author: wsp
* @Time    : 2018/4/11 16:45
* @Description: 有限状态机
 */
package fsmStrudy

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

func TestFsmStudy(t *testing.T) {
    FsmStudy()
}

func TestFsmStudy2(t *testing.T) {
    //创建一个状态机
    //三个参数:1.默认状态 2.定义状态事件 3.定义状态转变时调用的函数
    fsm := fsm.NewFSM(
        "green",
        fsm.Events{
            //状态事件的名称   该事件的起始状态Src         该事件的结束状态Dst
            //即:状态事件warn(警告事件)表示事物的状态从状态green到状态yellow
            {Name: "warn", Src: []string{"green"}, Dst: "yellow"},
            {Name: "panic", Src: []string{"yellow"}, Dst: "red"},
            {Name: "yellow", Src: []string{"red"}, Dst: "blue"},
            {Name: "calm", Src: []string{"red"}, Dst: "yellow"},
        },
        //状态事件调用函数,在此称为 时机函数。关键字用'_'隔开,格式是:"调用时机_事件或状态"
        //before表示在该事件或状态发生之前调用该函数,如"before_warn",表示在warn
        //这个状态事件发生前调用这个函数。"before_yellow"表示进入yellow状态之前调用
        //该函数。
        //依此类推,after表示在...之后,enter表示在进入...之时,leave表示在离开...
        //之时。
        fsm.Callbacks{
            //fsm内定义的状态事件函数,关键字指定的是XXX_event和XXX_state
            //表示任一的状态或状态事件
            "before_event": func(e *fsm.Event) {
                fmt.Println("before_event")
            },
            "leave_state": func(e *fsm.Event) {
                fmt.Println("leave_state")
            },
            //根据自定义状态或事件所定义的状态事件函数
            "before_yellow": func(e *fsm.Event) {
                fmt.Println("before_yellow")
            },
            "before_warn": func(e *fsm.Event) {
                fmt.Println("before_warn")
            },
        },
    )
    //打印当前状态,输出是默认状态green
    fmt.Println(fsm.Current())
    //触发warn状态事件,状态将会从green转变到yellow
    //同时触发"before_warn"、"before_yellow"、"before_event"、"leave_state"函数
    fsm.Event("warn")
    fmt.Println("======================")
    fsm.Event("panic")
    fmt.Println("======================")
    fsm.Event("yellow")
    //打印当前状态,输出状态是yellow
    fmt.Println(fsm.Current())
}

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go 技巧: 实现一个无限 buffer 的 channel发布时间:2022-07-10
下一篇:
go学习笔记 禁止拷贝noCopy发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap