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 directly
FlagSet
ObjectCommandLine
, it is fully compatible; otherwise when you instantiate it manuallyFlagSet
Object, 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. inip
andport
Allint
Type flag,host
The logo is customizedhost
Type, it implementsInterface, by implementing interface types, flags can support any type, increasing flexibility.
pass--help/-h
Parameters 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.
ip
The default parameters of the flag are1234
,port
The 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--help
The 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
ip
The default value of the flag has been command line parameters1
Covered, because no deliveryport
flag, so the print result is the default value8080
,host
The value of the flag can also be printed normally.
There are 4 non-optional parametersx
、y
、a
、b
They 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.x
、y
The 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 passCustomized
FlagSet
Objectflagset
, the subsequent flag definition and parsing are all passedflagset
Come and finish.
In the previous example()
This usage actually uses the globalFlagSet
ObjectCommandLine
,CommandLine
Definition 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 string
parameter(The second parameter of
and
The 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>Var
The class method name containsVar
For keywords, the flag parameter value will be bound to the parameter of the first pointer type. -
pflag.<Type>P
、pflag.<Type>VarP
The class method name isP
Ending, 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-
。
= false
The function is to prohibit reordering flags when printing help information.
Example Lastly, use()
Gets the value of the parameter.
pass--help/-h
Parameters 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-b
and--boolVar
It 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 1
Specify with full flagip
Parameter value.
pass-H localhost
Specify using short flagshost
Parameter value.
Boolean flag specifies parameters--boolVar=false
Need 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.
Duration
Sign 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 function
normalizeFunc
, and then pass it through(normalizeFunc)
Injected intoflagset
Make it effective.
existnormalizeFunc
In the function, we givenew-flag-name
A 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
NoOptDefVal
yesno option default values
abbreviation of .
After creating the flag, you can set it for the flagNoOptDefVal
Attribute, if the flag hasNoOptDefVal
Properties and flags are set on the command line without parameter options, then the flags will be set toNoOptDefVal
Specified 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 used
A short flag can be deprecated and used
A 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 (&boolVar, "boolVar", "b", true, "help message for boolVar") var h string (&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 isip
When, its corresponding short signi
It will also be deprecated;boolVar
The corresponding short signb
hour,boolVar
The logo will be retained;host
The 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 messageip
The flag has been deprecated, but used--ip 1
The specified parameter value can still take effect.
Hiddenhost
Logo usage-H localhost
The 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-b
A deprecated prompt, the specified parameter value still takes effect.
For deprecatedip
Logo, use a short logo to spread miserable-i 1
Also 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,ip
The logo is used()
Declared,port
The logo is used()
Declared. Just passAddGoFlagSet
Method 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>P
Method 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 introduced
NoOptDefVal
What 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 exampleip
The name of the logo actually representsint pointer
InsteadInternet Protocol Address
。ip
The logo comes from the official example, but I followed the trend and declared it againport
、host
The 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!