Trusted answers to developer questions

How to use the Flag package in Golang

Get Started With Data Science

Learn the fundamentals of Data Science with this free course. Future-proof your career by adding Data Science skills to your toolkit — or prepare to land a job in AI, Machine Learning, or Data Analysis.

Flags are useful because they let you create options when running command-line programs. With flags, you can create programs that effectively accomplish multiple use cases. In Golang, you can use the flag package to parse, create, and use flags. In this shot, we will go over how to use the package to create command-line flags and command-line subcommands.

A typical command line prompt is in format 'program command flag'
A typical command line prompt is in format 'program command flag'

Command-line flags

Defining flags is easy, you can set them up using flag.String(), flag.Bool(), flag.Int(), etc.

import "flag"
flagPtr := flag.String("<identifier>", "<defaultOutput>", "<help message>")

You may need to bind a flag to a variable. You can accomplish by:

var flagvar string
func init() {
  flag.StringVar(&flagvar, "<identifier>", "<defaultOutput>", "<help message>")
}

After you’ve defined your flags, you need to call flag.Parse(). This call will execute command-line parsing and will let you use the flags.

Flags themselves are pointers. If you bind them to variables, they become values. You can learn more about flags in the official documentation.

package main
import (
"flag"
"fmt"
)
func main() {
wordPtr := flag.String("flavor", "vanilla", "select shot flavor")
numbPtr := flag.Int("quantity", 2, "quantity of shots")
boolPtr := flag.Bool("cream", false, "decide if you want cream")
var order string
flag.StringVar(&order, "order", "complete", "status of order")
flag.Parse()
fmt.Println("flavor:", *wordPtr)
fmt.Println("quantity:", *numbPtr)
fmt.Println("cream:", *boolPtr)
fmt.Println("order:", order)
fmt.Println("tail:", flag.Args())
}

Assume the program above is called coffee.go.

To run this file, you would run the command:

go build coffee.go

With the binary built, you can call it like you would any command-line utility with the flags of your choice. If you do not provide a value to the flags, they will use the default value. Any tag not defined in the program can be stored and accessed using the flag.Args() method. You can specify the flag by passing the index value ii to flag.Args(i).

package main

import (
    "flag"
    "fmt"
)

func main() {

    wordPtr := flag.String("flavor", "vanilla", "select shot flavor")
    numbPtr := flag.Int("quantity", 2, "quantity of shots")
    boolPtr := flag.Bool("cream", false, "decide if you want cream")

    var order string
    flag.StringVar(&order, "order", "complete", "status of order")

    flag.Parse()

    fmt.Println("flavor:", *wordPtr)
    fmt.Println("quantity:", *numbPtr)
    fmt.Println("cream:", *boolPtr)
    fmt.Println("order:", order)
    fmt.Println("tail:", flag.Args())
}

To run the code, type go build coffee.go first.

Expected output

$ ./coffee -flavor=chocolate -cream -order=incomplete
flavor: chocolate
quantity: 2
cream: true
order: incomplete
tail: []
$ ./coffee -flavor=chocolate -cream -order=incomplete -flag1 -flag2=true
flavor: chocolate
quantity: 2
cream: true
order: incomplete
tail: [flag1 flag2=true]

Use the h or --help flag to automatically generate the help text for the command-line program.

Command-Line Subcommands

Think of subcommands as major options for a command that can be further configured using flags of their own. For instance, consider the go build command, where build is the subcommand. To set-up a subcommand, use NewFlagSet method. After making the call, you can add flags to the call using the following syntax:

subCmd := flag.NewFlagSet("sub",flag.ExitOnError)
flagOne := subCmd.Bool("flagKeyword", false, "description") 

Let’s look at the example below to get a clearer understanding:

package main

import (
    "flag"
    "fmt"
    "os"
)

func main() {

    subOne := flag.NewFlagSet("one", flag.ExitOnError)
    oneCream := subOne.Bool("cream", false, "Cream")
    oneSugar := subOne.String("sugar", "", "Sugar")

    subTwo := flag.NewFlagSet("two", flag.ExitOnError)
    twoTea := subTwo.Int("tea", 0, "Tea")

    if len(os.Args) < 2 {
        fmt.Println("expected 'one' or 'two' subcommands")
        os.Exit(1)
    }

    switch os.Args[1] {

    case "one":
        subOne.Parse(os.Args[2:])
        fmt.Println("subcommand 'one'")
        fmt.Println("  Cream:", *oneCream)
        fmt.Println("  Sugar:", *oneSugar)
        fmt.Println("  tail:", subOne.Args())
    case "two":
        subTwo.Parse(os.Args[2:])
        fmt.Println("subcommand 'two'")
        fmt.Println("  tea:", *twoTea)
        fmt.Println("  tail:", subTwo.Args())
    default:
        fmt.Println("expected 'one' or 'two' subcommands")
        os.Exit(1)
    }
}

To run the code, type go build coffee.go first.

Expected output

$ ./coffee one -cream -sugar=brown
subcommand 'one'
  Cream: true
  Sugar: brown
  tail: []
$ ./coffee two -tea 5
subcommand 'two'
  Tea: 5
  tail: []

RELATED TAGS

golang

CONTRIBUTOR

Abdul Moeed Asad
Copyright ©2024 Educative, Inc. All rights reserved
Did you find this helpful?