About
This post takes a look at one of the first modules I learned to use as a Go programmer: the flag module from the Go standard library.
Flags
Context
The flag module provides a library that is capable of parsing command-line options. A common pattern is to define each command-line option as a package-local variable, with one package-local variable per flag.
The flag module can be especially nice when it is combined with a
package-level init function that is run when a package is
initialized. This is the perfect place to initialize and parse our flags.
Let's materialize our idea into something concrete, with the
package-level help and username variables being
used to store our flag values:
package main
import (
"flag"
)
var help bool
var username string
func init() {
flag.BoolVar(&help, "h", false, "Show help")
flag.StringVar(&username, "u", "", "Set username")
flag.Parse()
}
Explanation
The flag.BoolVar and flag.StringVar function
binds a flag to a package-local variable. The first argument is a pointer
to the variable where we want to store a flag value, the second argument
is the flag, the third argument is a default value, and the fourth
argument describes the flag. Finally, we parse os.Args with
the call to flag.Parse() and this sets up our main method to
receive flag variables that have been populated.
Main
Context
The previous example sets us up nicely to implement the
main function and receive the parsed flag options:
package main
import (
"fmt"
"flag"
"os"
)
var help bool
var username string
func main() {
if help {
fmt.Printf("usage: %s\n", os.Args[0])
} else if len(username) > 0 {
fmt.Printf("Hello, %s!", username)
} else {
fmt.Printf("Hello, anonymous")
}
}
func init() {
flag.BoolVar(&help, "h", false, "Show help")
flag.StringVar(&username, "u", "", "Set username")
flag.Parse()
}
Explanation
The above sample first runs the init function, and parses
our flags into a set of package-level variables. By the time the
main function executes, the flag variables have been
initialized. We can then implement logic on top of our flag variables.
That's more or less it, this is a simple and idiomatic pattern for
parsing command line options in Go.
Conclusion
The flag package can help Go programmers write command-line applications in idiomatic Go. It is both useful and practical for everyday Go applications.