SoFunction
Updated on 2025-03-03

Guide to using pflag in Go language command line parameter parsing tool

During the development process using Go, command line parameter analysis is a requirement we often encounter. Although the Go standard library provides flag packages for implementing command line parameter resolution, they can only meet basic needs and do not support advanced features. So a third-party package called pflag appeared in the Go community, which has more comprehensive and powerful functions. In this article, we will learn and master how to use pflag.

Features

As a replacement for Go's built-in flag package, pflag has the following features:

  • Implements POSIX/GNU style --flags.
  • pflag is compatible with the POSIX recommended syntax in the "25.1.1 Program Parameter Syntax Convention" chapter in "The GNU C Library".
  • Compatible with flag packages in the Go standard library. If you use the global definition of the flag package directlyFlagSetObjectCommandLine, it is fully compatible; otherwise when you instantiate it manuallyFlagSetObject, then you need to set a short flag for each flag (Shorthand)。

use

Basic usage

We can use pflag like we do with the flag package from the Go standard library.

package main

import (
 "fmt"

 "/spf13/pflag"
)

type host struct {
 value string
}

func (h *host) String() string {
 return 
}

func (h *host) Set(v string) error {
  = v
 return nil
}

func (h *host) Type() string {
 return "host"
}

func main() {
 var ip *int = ("ip", 1234, "help message for ip")

 var port int
 (&port, "port", 8080, "help message for port")

 var h host
 (&h, "host", "help message for host")

 // parse command line parameters ()

 ("ip: %d\n", *ip)
 ("port: %d\n", port)
 ("host: %+v\n", h)

 ("NFlag: %v\n", ()) // Returns the number of command line flags that have been set ("NArg: %v\n", ())   // Return the number of parameters remaining after processing the flag ("Args: %v\n", ())   // Return to the remaining parameter list after processing the flag ("Arg(1): %v\n", (1)) // Return to the i-th item in the remaining parameter list after processing the flag}

The pflag usage demonstrated in the above example is the same as the flag package usage, which allows seamless replacement of the two.

Examples are used separately()()()Three different ways to declare the logo. inipandportAllintType flag,hostThe logo is customizedhostType, it implementsInterface, by implementing interface types, flags can support any type, increasing flexibility.

pass--help/-hParameters to view command line program usage help:

$ go run  --help                      
Usage of ./main:
      --host host   help message for host
      --ip int      help message for ip (default 1234)
      --port int    help message for port (default 8080)
pflag: help requested

It can be found that the flag positions in the help information are reordered, not the order in which the flags are defined.

Unlike the flag package, the pflag package parameter delimiter is two-, not one-, in pflag--and-It has different meanings, which will be introduced later.

ipThe default parameters of the flag are1234portThe default parameters of the flag are8080

Note: After executing the program in some terminals, one more line will be printed.exit status 2, this does not mean that the program does not exit normally, but because--helpThe intention is to view the use help, so the program actively calls it after printing the use help information.(2)Exit.

Use the command line program in the following way:

$ go run  --ip 1 x y --host localhost a b 
ip: 1
port: 8080
host: {value:localhost}
NFlag: 2
NArg: 4
Args: [x y a b]
Arg(1): y

ipThe default value of the flag has been command line parameters1Covered, because no deliveryportflag, so the print result is the default value8080hostThe value of the flag can also be printed normally.

There are 4 non-optional parametersxyabThey were also identified and recorded by pflag. This is more powerful than flag. In the flag package, the number of non-option parameters can only be written at the end of all command line parameters.xyThe program will report an error when it appears here.

Advanced usage

In addition to usage like flag packages, pflag also supports some unique usages, and the following is an usage example.

package main

import (
 "fmt"
 "os"

 "/spf13/pflag"
)

type host struct {
 value string
}

func (h *host) String() string {
 return 
}

func (h *host) Set(v string) error {
  = v
 return nil
}

func (h *host) Type() string {
 return "host"
}

func main() {
 flagset := ("test", )

 var ip = ("ip", "i", 1234, "help message for ip")

 var boolVar bool
 (&boolVar, "boolVar", "b", true, "help message for boolVar")

 var h host
 (&h, "host", "H", "help message for host")

  = false

 ([1:])

 ("ip: %d\n", *ip)
 ("boolVar: %t\n", boolVar)
 ("host: %+v\n", h)

 i, err := ("ip")
 ("i: %d, err: %v\n", i, err)
}

First we passCustomizedFlagSetObjectflagset, the subsequent flag definition and parsing are all passedflagsetCome and finish.

In the previous example()This usage actually uses the globalFlagSetObjectCommandLineCommandLineDefinition is as follows:

var CommandLine = NewFlagSet([0], ExitOnError)

Now there are three different ways to declare flags, respectively()()(). It is not difficult to find that there is one more ending in the naming of these three methods.P, their abilities have been upgraded, and there is one more in all three methods.shorthand stringparameter(The second parameter ofandThe third parameter of ) is used to set the short flag.

From the method names that declare flags, we can summarize some rules:

  • pflag.<Type>The class method name stores the flag parameter value in the pointer and returns.
  • pflag.<Type>VarThe class method name containsVarFor keywords, the flag parameter value will be bound to the parameter of the first pointer type.
  • pflag.<Type>Ppflag.<Type>VarPThe class method name isPEnding, short logo is supported.

The delimiter used for a complete flag when passing arguments on the command line is--, while a short flag delimiter is-

= falseThe function is to prohibit reordering flags when printing help information.

Example Lastly, use()Gets the value of the parameter.

pass--help/-hParameters to view command line program usage help:

$ go run  --help
Usage of test:
  -i, --ip int      help message for ip (default 1234)
  -b, --boolVar     help message for boolVar (default true)
  -H, --host host   help message for host
pflag: help requested

In this help message, the order of flags has not been changed, that is, the order of declarations.

Each sign corresponds to a short sign, such as-band--boolVarIt is equivalent and can set parameters more conveniently.

Specify the following command line parameters to run the example:

$ go run  --ip 1 -H localhost --boolVar=false
ip: 1
boolVar: false
host: {value:localhost}
i: 1, err: <nil>

pass--ip 1Specify with full flagipParameter value.

pass-H localhostSpecify using short flagshostParameter value.

Boolean flag specifies parameters--boolVar=falseNeed to use an equal sign=Not spaces.

Command line flag syntax

The command line flags follow the following syntax:

grammar illustrate
--flag Applicable to bool type flags, or flags with NoOptDefVal attribute.
--flag x Applicable to non-bool type flags, or flags without the NoOptDefVal attribute.
--flag=x Applicable to bool type flags.
-n 1234/-n=1234/-n1234 Short flag, non-bool type and no NoOptDefVal attribute, all three are equivalent.

Flag parsing in terminator--Stop afterwards.

The integer flag accepts 1234, 0664, 0x1234 and may be negative.

The Boolean flag accepts 1, 0, t, f, true, false, TRUE, FALSE, True, False.

DurationSign accepts any pairValid input.

Logo name Normalize

With the helpWe can give one or more aliases to the logo, standardized logo names, etc.

package main

import (
 "fmt"
 "os"
 "strings"

 "/spf13/pflag"
)

func normalizeFunc(f *, name string)  {
 // alias
 switch name {
 case "old-flag-name":
  name = "new-flag-name"
  break
 }

 // --my-flag == --my_flag == --
 from := []string{"-", "_"}
 to := "."
 for _, sep := range from {
  name = (name, sep, to, -1)
 }
 return (name)
}

func main() {
 flagset := ("test", )

 var ip = ("new-flag-name", "i", 1234, "help message for new-flag-name")
 var myFlag = ("my-flag", "m", 1234, "help message for my-flag")

 (normalizeFunc)
 ([1:])

 ("ip: %d\n", *ip)
 ("myFlag: %d\n", *myFlag)
}

To use, we need to create a functionnormalizeFunc, and then pass it through(normalizeFunc)Injected intoflagsetMake it effective.

existnormalizeFuncIn the function, we givenew-flag-nameA logo named an aliasold-flag-name

In addition, the logo name has been standardized with-and_The flag name of the splitter will be uniformly standardized into.The flag name as the separator.

Examples of use are as follows:

$ go run  --old-flag-name 2 --my-flag 200
ip: 2
myFlag: 200

$ go run  --new-flag-name 3 --my_flag 300
ip: 3
myFlag: 300

NoOptDefVal

NoOptDefValyesno option default valuesabbreviation of .

After creating the flag, you can set it for the flagNoOptDefValAttribute, if the flag hasNoOptDefValProperties and flags are set on the command line without parameter options, then the flags will be set toNoOptDefValSpecified value.

The following example:

var ip = ("flagname", "f", 1234, "help message")
("flagname").NoOptDefVal = "4321"

The results of different parameters are as follows:

Command line parameters Result Value
--flagname=1357 ip=1357
--flagname ip=4321
[nothing] ip=1234

Deprecated/hide flags

useA flag can be deprecated and usedA short flag can be deprecated and usedA logo can be hidden.

package main

import (
 "fmt"
 "os"

 "/spf13/pflag"
)

func main() {
 flags := ("test", )

 var ip = ("ip", "i", 1234, "help message for ip")

 var boolVar bool
 (&amp;boolVar, "boolVar", "b", true, "help message for boolVar")

 var h string
 (&amp;h, "host", "H", "127.0.0.1", "help message for host")

 // Deprecated flag ("ip", "deprecated")
 ("boolVar", "please use --boolVar only")

 // Hide the logo ("host")

 ([1:])

 ("ip: %d\n", *ip)
 ("boolVar: %t\n", boolVar)
 ("host: %+v\n", h)
}

Check the help for use:

$ go run  -h                                 
Usage of test:
      --boolVar   help message for boolVar (default true)
pflag: help requested

From the print results, you can find that the deprecated flag isipWhen, its corresponding short signiIt will also be deprecated;boolVarThe corresponding short signbhour,boolVarThe logo will be retained;hostThe logo is completely hidden.

Specify the following command line parameters to run the example:

$ go run  --ip 1 --boolVar=false -H localhost
Flag --ip has been deprecated, deprecated
ip: 1
boolVar: false
host: localhost

The user will be prompted when printing the messageipThe flag has been deprecated, but used--ip 1The specified parameter value can still take effect.

HiddenhostLogo usage-H localhostThe specified parameter value can also take effect.

Specify the following command line parameters to run the example:

$ go run  -i 1 -b=false --host localhost
Flag --ip has been deprecated, deprecated
Flag shorthand -b has been deprecated, please use --boolVar only
ip: 1
boolVar: false
host: localhost

A short logo has been added to the print message-bA deprecated prompt, the specified parameter value still takes effect.

For deprecatedipLogo, use a short logo to spread miserable-i 1Also effective.

Support flag types

Since pflag is compatible with flag packages, you can mix the two in one program:

package main

import (
 "flag"
 "fmt"

 "/spf13/pflag"
)

func main() {
 var ip *int = ("ip", 1234, "help message for ip")
 var port *int = ("port", 80, "help message for port")

 ()
 ()

 ("ip: %d\n", *ip)
 ("port: %d\n", *port)
}

in,ipThe logo is used()Declared,portThe logo is used()Declared. Just passAddGoFlagSetMethod willRegister in pflag, then pflag can use the flag collection declared in the flag.

The results of the running example are as follows:

$ go run --ip 10 --port 8000
ip: 10
port: 8000

Summarize

This article mainly introduces the characteristics and usage of Go third-party logo package pflag.

First, we introduce the basic usage methods of pflag, including declaring flags, parsing command line parameters, obtaining flag values, etc. Then introduce the advanced usage of pflag, such as customizationFlagSet,usepflag.<Type>PMethod to support short flags. Later, the command line flag syntax was explained, and there are different syntaxes for Boolean, non-Boolean and short flags. We also explained how to use itGive one or more aliases and standardize the logo. Then introducedNoOptDefValWhat is the role and how to deprecate/hide flags. Finally, we demonstrate how to mix flags and pflags in a program through examples.

Easter egg: I don't know if you have found it, in the exampleipThe name of the logo actually representsint pointerInsteadInternet Protocol AddressipThe logo comes from the official example, but I followed the trend and declared it againporthostThe logo is considered a homophone in a program :).

The above is the detailed content of the guide to using pflag in the command line parameter analysis tool in Go. For more information about Go pflag command line parameter analysis, please pay attention to my other related articles!