首页 > 其他分享 >Go每日一库之134:fsm(基有限状态机库)

Go每日一库之134:fsm(基有限状态机库)

时间:2023-09-29 21:11:35浏览次数:39  
标签:string err fmt fsm 一库 Dst 134 Event

开发中,我们经常会遇到这种情况,服务模块有多种状态,它们有一定的顺序,先后执行,逐步切换。这时,fsm这个库可以帮助我们更好的管理多个状态。

fsm库,它主要基于两个FSM实现,增加了golang版本的实现:

简单举例

package main

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

func enterState(e *fsm.Event) {
 fmt.Printf("event: %s, from:%s to %s\n", e.Event, e.Src, e.Dst)
}

func main() {
 f := fsm.NewFSM(
  "sleeping",
  fsm.Events{
   {Name: "eat", Src: []string{"sleeping"}, Dst: "eating"},
   {Name: "work", Src: []string{"eating"}, Dst: "working"},
   {Name: "sleep", Src: []string{"working"}, Dst: "sleeping"},
  },
  fsm.Callbacks{
   "enter_state": func(e *fsm.Event) { enterState(e) },
  },
 )

err := f.Event("eat")
 if err != nil {
  fmt.Println(err)
 }

err = f.Event("work")
 if err != nil {
  fmt.Println(err)
 }

err = f.Event("sleep")
 if err != nil {
  fmt.Println(err)
 }

}

执行,控制台输出如下:

$ go run test.go

event: eat, from:sleeping to eating
event: work, from:eating to working
event: sleep, from:working to sleeping

结构体举例

package main

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, event: %s, from:%s to %s\n", d.To, e.Event, e.Src, e.Dst)
}

func main() {
 door := NewDoor("zhang san")

err := door.FSM.Event("open")
 if err != nil {
  fmt.Println(err)
 }

err = door.FSM.Event("close")
 if err != nil {
  fmt.Println(err)
 }
}

执行,控制台输出如下:

$ go run test.go

The door to zhang san, event: open, from:closed to open
The door to zhang san, event: close, from:open to closed

总结

fsm 是一个非常简单,好用的状态机管理库。如果你各种状态切换的需求,不妨试试看,相信一定会喜欢上的!

参考资料

标签:string,err,fmt,fsm,一库,Dst,134,Event
From: https://www.cnblogs.com/arena/p/17737343.html

相关文章

  • Go每日一库之65:tunny
    简介之前写过一篇文章介绍了ants这个goroutine池实现。当时在网上查看相关资料的时候,发现了另外一个实现tunny。趁着时间相近,正好研究一番。也好比较一下这两个库。那就让我们开始吧。快速开始本文代码使用GoModules。创建目录并初始化:$mkdirtunny&&cdtunny$gomo......
  • Go每日一库之64:ants(源码赏析)
    简介继上一篇Go每日一库之ants,这篇文章我们来一起看看ants的源码。Pool通过上篇文章,我们知道ants池有两种创建方式:p,_:=ants.NewPool(cap):这种方式创建的池子对象需要调用p.Submit(task)提交任务,任务是一个无参数无返回值的函数;p,_:=ants.NewPoolWithFunc(cap,func......
  • Go每日一库之63:ants
    简介处理大量并发是Go语言的一大优势。语言内置了方便的并发语法,可以非常方便的创建很多个轻量级的goroutine并发处理任务。相比于创建多个线程,goroutine更轻量、资源占用更少、切换速度更快、无线程上下文切换开销更少。但是受限于资源总量,系统中能够创建的goroutine数量......
  • Go每日一库之55:quicktemplate
    简介最近在整理我们项目代码的时候,发现有很多活动的代码在结构和提供的功能上都非常相似。为了方便今后的开发,我花了一点时间编写了一个生成代码框架的工具,最大程度地降低重复劳动。代码本身并不复杂,且与项目代码关联性较大,这里就不展开介绍了。在这个过程中,我发现Go标准的模板......
  • Go每日一库之54:quicktemplate(增强模板库)
    简介最近在整理我们项目代码的时候,发现有很多活动的代码在结构和提供的功能上都非常相似。为了方便今后的开发,我花了一点时间编写了一个生成代码框架的工具,最大程度地降低重复劳动。代码本身并不复杂,且与项目代码关联性较大,这里就不展开介绍了。在这个过程中,我发现Go标准的模板......
  • Go每日一库之53:commonregex
    简介有时,我们会遇到一些需要使用字符串的匹配和查找的任务。并且我们知道这种情况下,使用正则表达式是最简洁和优雅的。为了完成某个任务特地去系统地学习正则表达式费时费力,而且一段时间不用又很容易遗忘。下次遇到问题还要再重复这个过程。commonregex库来了,它内置很多常用的正......
  • Go每日一库之52:commonregex
    简介有时,我们会遇到一些需要使用字符串的匹配和查找的任务。并且我们知道这种情况下,使用正则表达式是最简洁和优雅的。为了完成某个任务特地去系统地学习正则表达式费时费力,而且一段时间不用又很容易遗忘。下次遇到问题还要再重复这个过程。commonregex库来了,它内置很多常用的正......
  • Go每日一库之51:gabs
    简介JSON是一种非常流行的数据交换格式。每种编程语言都有很多操作JSON的库,标准库、第三方库都有。Go语言中标准库内置了JSON操作库encoding/json。我们之前也介绍过专门用于查询JSON串的库gjson和专门用于修改JSON串的库sjson,还有一个非常方便的操作JSON数据的命令......
  • Go每日一库之50:jobrunner
    简介我们在Web开发中时常会遇到这样的需求,执行一个操作之后,需要给用户一定形式的通知。例如,用户下单之后通过邮件发送电子发票,网上购票支付后通过短信发送车次信息。但是这类需求并不需要非常及时,如果放在请求流程中处理,会影响请求的响应时间。这类任务我们一般使用异步的方式......
  • Go每日一库之49:mapstructure
    简介mapstructure用于将通用的map[string]interface{}解码到对应的Go结构体中,或者执行相反的操作。很多时候,解析来自多种源头的数据流时,我们一般事先并不知道他们对应的具体类型。只有读取到一些字段之后才能做出判断。这时,我们可以先使用标准的encoding/json库将数据解码为map......