On Wed, 23 Aug 2017 09:48:14 BST roger peppe <rogpe...@gmail.com> wrote: > On 23 August 2017 at 09:40, roger peppe <rogpe...@gmail.com> wrote: > > On 23 August 2017 at 09:23, MartinG <gar...@gmail.com> wrote: > >> Thanks for the fantastic explanation folks. > >> > >> I wonder if I can ask advice on how to improve my use case. I have a stru > ct > >> type that represents a state machine and each state is handled by a > >> different method on that type, each with the same signature I use a > >> function variable to represent the current state and it is simply set to > >> point at one of the methods. The state is modified frequently, hence my > >> problem. > >> > >> The options I can think of are: > >> > >> 1) Define another type (probably based on int or similar) representing the > >> current state and switch on that instead of using a function type. This > >> feels inelegant and avoids using function types on one of the scenarios th > ey > >> seem to be designed for. > >> 2) Define non-method related functions with a similar signature, but that > >> also take my base type as an additional parameter. I believe this will > >> avoid the allocation, but also feels wrong because these functions really > >> "belong" to my base type so should be methods. > >> > >> Any other possibilities? > > > > You could use method expressions. > > > > For example: > > > > https://play.golang.org/p/9H1n-CevNJ > > Actually, it occurs to me that using method expressions in this way is > actually more powerful, because the state can be manipulated independently > of the state transitions. You could use this, for example, to fork the > state machine and run it concurrently from an arbitrary state.
I find regular functions much cleaner (and a closer analog of a digital FSM). See for example: https://play.golang.org/p/MpX_lNT4rS Basically type state func(inputType) state func reset() { return initial } func initial(i inputType) state { if needChange(i) { return stateOne } return initial } func stateOne(i inputType) state { // etc. etc. } func main() { s := reset() for s != nil { s := s(readInput()) } } and so on. This is a Mealy machine, where the next state depends on the current state and current input (in s/w not much use for a Moore machine unless you are driving/simulating some regular physical process, in which case you don't need any input parameter). If you want a side effecting FSM, pass in a ptr to some mutable state. Since these are essentially pure functions you can run them in parallel. I tend to think use of methods requires more boilerplate and is more obfuscating. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.