Jida's Blog

Golang Standard Package: flag

18th November 2024
Golang
Golang Standard Package
CLI
Last updated:25th January 2025
3 Minutes
520 Words

Package flag implements CLI flag parsing.

Specifications

0. Intro

Let’s start with a simple example:

1
package main
2
3
import (
4
"flag"
5
"fmt"
6
"time"
7
)
8
9
// 1. Define flag varaibles
10
var (
11
host string
12
port int
13
isTestMode bool
14
timeout time.Duration
15
)
16 collapsed lines
16
17
func main() {
18
// 2. Bind flags to varaibles
19
flag.StringVar(&host, "host", "localhost", "db host")
20
flag.IntVar(&port, "port", 3306, "db port")
21
flag.BoolVar(&isTestMode, "isTest", true, "isTestMode")
22
flag.DurationVar(&timeout, "timeout", 5*time.Second, "db timeout")
23
24
//3. Parse he command line into the defined flags
25
flag.Parse()
26
27
fmt.Println("host:", host)
28
fmt.Println("port:", port)
29
fmt.Println("isTestMode:", isTestMode)
30
fmt.Println("timeout:", timeout)
31
}

output:

Terminal window
1
go run main.go
2
host: localhost
3
port: 3306
4
isTestMode: true
5
timeout: 5s
6
7
go run main.go -port 4000 -timeout 30s
8
host: localhost
9
port: 4000
10
isTestMode: true
11
timeout: 30s

2. Procedures

  1. Define flag varaibles
  2. Bind flags to varaibles
  3. Parse he command line into the defined flags using flag.Parse()

3. Command line flag syntax

The following forms are allowed:

  1. -flag or --flag: only for boolean flags.
  2. -flag=x: use for all types
  3. -flag x: for non-boolean flags only
Terminal window
1
// isProd is in default true in this example:
2
go run main.go --isProd false
3
isProdMode: true
4
go run main.go --isProd=false
5
isProdMode: false

4. Two types of functions

flag.typeVar v.s. flag.type

1
func StringVar(p *string, name string, value string, usage string)
2
func BoolVar(p *bool, name string, value bool, usage string)
3
func IntVar(p *int, name string, value int, usage string)
4
func DurationVar(p *time.Duration, name string, value time.Duration, usage string)
5
6
func String(name string, value string, usage string) *string
7
func Bool(name string, value bool, usage string) *bool
8
func Int(name string, value int, usage string) *int
9
func Duration(name string, value time.Duration, usage string) *time.Duration
flag.typeVar
1
var x int
2
flag.IntVar(x, "x", 10, "define x")
3
4
// flag.type
5
var y = flag.Int("y", 20, "define y")

5. Custom type

If we want to define custom type for CLI, we need to implement the Value interface for the new type:

1
type Value interface {
2
String() string // print value
3
Set(string) error // set flag value
4
}
5
6
type ClusterArray []int
7
8
func (arr *ClusterArray) Set(val string) error {
9
// disable the flag to be set multiple times
10
if len(*arr) > 0 {
11
return errors.New("cluster flag already set")
12
}
13
// type convertion
14
for _, val := range strings.Split(val, ",") {
15
cluster, err := strconv.Atoi(val)
23 collapsed lines
16
if err != nil {
17
return err
18
}
19
*arr = append(*arr, cluster)
20
}
21
return nil
22
}
23
24
func (arrs *ClusterArray) String() string {
25
str := "["
26
for _, s := range *arrs {
27
str += strconv.Itoa(s)
28
}
29
str += "]"
30
return str
31
}
32
33
func main() {
34
var clusters ClusterArray
35
flag.Var(&clusters, "clusters", "db clusters")
36
flag.Parse()
37
fmt.Println("clusters:", clusters)
38
}

output:

Terminal window
1
go run main.go -clusters=1,4,6
2
clusters: [1,4,6]
3
4
go run main.go -clusters=1,2 -clusters=5
5
invalid value "5" for flag -clusters: cluster flag already set
6
7
go run main.go -clusters=1,2,i
8
9
invalid value "1,2,i" for flag -clusters: strconv.Atoi: parsing "i": invalid syntax

6. Shorthand

1
func main() {
2
var port int
3
flag.IntVar(&port, "p", 3306, "db port (shorthand)")
4
flag.IntVar(&port, "port", 3306, "db port")
5
flag.parse()
6
fmt.Println("port:", port)
7
}

output:

1
go run main.go -p 1000
2
port: 1000
3
go run main.go -port 1000
4
port: 1000

You might find the complete example of codes in this repo: go-playground

References

  1. https://pkg.go.dev/flag
Article title:Golang Standard Package: flag
Article author:Jida-Li
Release time:18th November 2024