Translation Go (#golang) Implementation of the State machine

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Before the Spring Festival, a rough look at the public account. A simple package WeChat is implemented with Golang for access to public accounts. At that time, thinking, the text of the interactive process if you want to achieve a certain logical complex process, you may need to use the state machine. Then you see this article: "State Machines in Go" (#golang). Very well timed! Translate it here, readers!

--– Translation Divider Line--–

Go (#golang) Implementation of the State machine

I've rewritten a key service component with Go instead of Python. Because the Python interpreter is not thread-safe, a global lock is used when parsing. Unlike Python, Go has built-in concurrency support and is statically compiled.

The first step is to implement a state machine. The Python version is based on the David Mertz article.

Mertz uses an object-oriented form to define a class with data and methods. His code, aside from the syntax, is no stranger to anyone with object-oriented experience in C + +, C #, and Java.

However, Go does not provide a mechanism for an internal correlation method on a particular data structure. Instead, go allows federated methods to data structures so that any method can be applied to any structure. class {methods} and struct {}; The difference between methods. )

This form is close to what Alan Kay is saying about the initial object-oriented phase.

Let's not forget this, the following is the class of the state machine I started with the GO structure:

Type machine struct {    handlers   map[string]func (interface{}) (String, interface{})    Startstate string    Endstates  Map[string]bool}

Like the definition of Mertz, handlers is a string-key-name Map,map item that holds the value of a function, can receive an "item", and returns the next state name for the strings and updated item values.

Go thinks that functions are a class citizen object, so they are stored and passed in the same way as they do in Python.

I just made some changes at the end of the status list: Mertz uses a list of strings, but because there is no way to quickly locate in the Go list, I use Map (in Go, only iterate through the entire list of strings until a match is found).

Since the prototype of the processing function is cumbersome, I have built a custom function type for it:

Type Handler func (interface{}) (String, interface{}) type machine struct {    handlers   Map[string]handler    Startstate string    endstates  Map[string]bool}

The rest is the method of defining the association of the machine structure.

First define the two methods, one provides the state name associated to the handler function, and the other sets the end state:

Func (Machine *machine) addstate (HandlerName string, Handlerfn Handler) {machine    . Handlers[handlername] = Handlerfn}func (machine *machine) addendstate (EndState string) {machine    . Endstates[endstate] = true}

It is worth noting that since Endstates is a map (a list in the original version of Mertz), there can be multiple states for terminating the process.

The last method is used to execute the state machine, apply the appropriate handler function, and terminate when the end state is reached.

Because function collections are stored as first-class citizens in map, it is easy to find them based on their names and make calls:

Func (Machine *machine) Execute (Cargo interface{}) {    If handler, present: = machine. Handlers[machine. Startstate]; Present {        for {            nextstate, Nextcargo: = Handler (Cargo)            _, Finished: = machine. Endstates[nextstate]            If finished {                break            } else {                handler, present = machine. Handlers[nextstate]                cargo = Nextcargo            }        }    }

The only drawback is the strong type of Go, in the prototype of the processing function, you need to specify the type of the item.

Using generic interface{} as a type, all handlers need to type assert the input items so they can process any data (the test example uses floating point as the item, but it can be any data type, even a custom struct).

The full state machine has been released as a Go package.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.