While working with programming in Go I've developed some usage patterns that I thought might be worth jotting down.
Say we're developing a command-line tool that has a number of commands, something like @add@, @list@ and @rm@. We can declare a common form for command functions, like this:
typecommandfunc([]string)
So each command expects a list of arguments (for instance taken from @os.Args@). Then we can maintain a map of strings (the names of the commands) to commands.
which is a fairly straight-forward mapping from the command's name to the function it invokes.
Finally, the main function can be written in the following way:
import"os"funcmain(){iflen(os.Args)<2{usage()// Some kind of usage printingos.Exit(0)}ifcmd,ok:=commands[os.Args[1]];ok{cmd(os.Args[2:])// Strip away the command name }}
Adding a new command is easy. Simply implement a function (could be kept in its own @.go@ file) of type @func([]string)@ and add a new entry to the @commands@ map and it will be picked up automatically (upon recompilation).
I have to admit that sometimes Go's idea of mandatory braces annoys me a little. Even this short @main@ function requires two extra just for the closing brace. It would be interesting to see if the grammer could be changed to use a Pythonesque @if cond:@ syntax (with the colon indicating the end of the condition). Or, even just leaving out the opening brace could indicate that the next line be the single statement in the @if@ block.
On the other hand, the alternative @if@ syntax, allowing a declaration similar to a @for@-loop's initialisation, is pretty cool.
While we're speaking of slightly annoying Go things, consider a map of lists, the following will not work: