Go入门学习实例——有限状态机

安装好IDEA和GO插件,创建项目GoDemo

键入代码:

FSM.go

package src

import (
	"fmt"
	"sync"
)

type FSMState string //状态
type FSMEvent string //事件
type FSMHandler func() FSMState //处理方法,并返回新的状态

//有限状态机
type FSM struct {
	mu sync.Mutex  //排它锁
	state FSMState  //当前状态
	handlers map[FSMState]map[FSMEvent]FSMHandler  //处理地图集,每一个状态都可以出发有限个事件,执行有限个处理
}

//获取当前状态
func (f *FSM) getState() FSMState {
	return f.state
}

//设置当前状态
func (f *FSM) setState(newState FSMState) {
	f.state = newState
}

//某状态添加事件处理方式
func (f *FSM) AddHandler(state FSMState, event FSMEvent, handler FSMHandler) *FSM {
	if _, ok := f.handlers[state]; !ok {
		f.handlers[state] = make(map[FSMEvent]FSMHandler)
	}
	if _, ok := f.handlers[state][event]; ok {
		fmt.Print("[警告] 状态(%s)事件(%s)已定义过", state, event)
	}
	f.handlers[state][event] = handler
	return f
}

//事件处理
func (f *FSM) Call(event FSMEvent) FSMState {
	f.mu.Lock()
	defer f.mu.Unlock()
	events := f.handlers[f.getState()]
	if events == nil {
		return f.getState()
	}
	if fn,ok := events[event]; ok {
		oldState := f.getState()
		f.setState(fn())
		newState := f.getState()
		fmt.Println("状态从 [", oldState,"] 变成 [", newState, "]")
	}
	return f.getState()
}

//实例化FSM
func NewFSM(initState FSMState) *FSM {
	return &FSM{
		state: initState,
		handlers: make(map[FSMState]map[FSMEvent]FSMHandler),
	}
}

FSM_demo.go

package main

import (
	"fmt"
	. "./src"
)


var (
	//
	PowerOff = FSMState("关闭")
	FirstGear = FSMState("1档")
	SecondGear = FSMState("2档")
	ThirdGear = FSMState("3档")
	//
	PowerOffEvent = FSMEvent("按下关闭按钮")
	FirstGearEvent = FSMEvent("按下1档按钮")
	SecondGearEvent = FSMEvent("按下2档按钮")
	ThirdGearEvent = FSMEvent("按下3档按钮")
	//
	PowerOffHandler = FSMHandler(func() FSMState {
		fmt.Println("电风扇已关闭")
		return PowerOff
	})
	FirstGearHandler = FSMHandler(func() FSMState {
		fmt.Println("电风扇开启1档,微风徐来!")
		return FirstGear
	})
	SecondGearHandler = FSMHandler(func() FSMState {
		fmt.Println("电风扇开启2档,凉飕飕!")
		return SecondGear
	})
	ThirdGearHandler = FSMHandler(func() FSMState {
		fmt.Println("电风扇开启3档,发型被吹乱了!")
		return ThirdGear
	})
)

//电风扇
type ElectricFan struct {
	*FSM
}

//实例化电风扇
func NewElectricFan(initState FSMState) *ElectricFan {
	return &ElectricFan{
		FSM: NewFSM(initState),
	}
}

//入口函数
func main() {
	//电风扇实例
	efan := NewElectricFan(PowerOff)

	//关闭状态
	efan.AddHandler(PowerOff, PowerOffEvent, PowerOffHandler)
	efan.AddHandler(PowerOff, FirstGearEvent, FirstGearHandler)
	efan.AddHandler(PowerOff, SecondGearEvent, SecondGearHandler)
	efan.AddHandler(PowerOff, ThirdGearEvent, ThirdGearHandler)
	//1档状态
	efan.AddHandler(FirstGear, PowerOffEvent, PowerOffHandler)
	efan.AddHandler(FirstGear, FirstGearEvent, FirstGearHandler)
	efan.AddHandler(FirstGear, SecondGearEvent, SecondGearHandler)
	efan.AddHandler(FirstGear, ThirdGearEvent, ThirdGearHandler)
	//2档状态
	efan.AddHandler(SecondGear, PowerOffEvent, PowerOffHandler)
	efan.AddHandler(SecondGear, FirstGearEvent, FirstGearHandler)
	efan.AddHandler(SecondGear, SecondGearEvent, SecondGearHandler)
	efan.AddHandler(SecondGear, ThirdGearEvent, ThirdGearHandler)
	//3档状态
	efan.AddHandler(ThirdGear, PowerOffEvent, PowerOffHandler)
	efan.AddHandler(ThirdGear, FirstGearEvent, FirstGearHandler)
	efan.AddHandler(ThirdGear, SecondGearEvent, SecondGearHandler)
	efan.AddHandler(ThirdGear, ThirdGearEvent, ThirdGearHandler)

	//开始测试状态变化
	efan.Call(ThirdGearEvent);
	efan.Call(FirstGearEvent);
	efan.Call(PowerOffEvent);
	efan.Call(SecondGearEvent);
	efan.Call(PowerOffEvent);
}

 

运行结果:

D:\AI\IntelliJ-IDEA\bin\runnerw.exe D:\AI\Go\bin\go.exe run E:/各种语言/Go/projects/GoDemo/FSM_demo.go
电风扇开启3档,发型被吹乱了!
状态从 [ 关闭 ] 变成 [ 3档 ]
电风扇开启1档,微风徐来!
状态从 [ 3档 ] 变成 [ 1档 ]
电风扇已关闭
状态从 [ 1档 ] 变成 [ 关闭 ]
电风扇开启2档,凉飕飕!
状态从 [ 关闭 ] 变成 [ 2档 ]
电风扇已关闭
状态从 [ 2档 ] 变成 [ 关闭 ]

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值