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.