pflag 是 Go 的 flag 包的直接替代品,实现 POSIX/GNU 风格的 --flags。
pflag 与命令行选项的 POSIX 建议的 GNU 扩展兼容。有关更准确的描述,请参阅下面的“命令行标志语法”部分。
pflag 与 Go 语言具有相同风格的 BSD 许可证,可以在 LICENSE 文件中找到。
pflag 可使用标准go get
命令获得。
通过运行安装:
go get github.com/spf13/pflag
通过运行以下命令来运行测试:
go test github.com/spf13/pflag
pflag 是 Go 原生标志包的直接替代品。如果您以“flag”名称导入 pflag,那么所有代码都应该继续运行,无需任何更改。
import flag "github.com/spf13/pflag"
对此有一个例外:如果您直接实例化 Flag 结构,则还需要设置一个“Shorthand”字段。大多数代码从不直接实例化该结构,而是使用 String()、BoolVar() 和 Var() 等函数,因此不受影响。
使用 flag.String()、Bool()、Int() 等定义标志。
这声明了一个整数标志 -flagname,存储在指针 ip 中,类型为 *int。
var ip * int = flag . Int ( "flagname" , 1234 , "help message for flagname" )
如果您愿意,可以使用 Var() 函数将标志绑定到变量。
var flagvar int
func init () {
flag . IntVar ( & flagvar , "flagname" , 1234 , "help message for flagname" )
}
或者,您可以创建满足 Value 接口(带有指针接收器)的自定义标志,并将它们耦合到标志解析:
flag . Var ( & flagVal , "name" , "help message for flagname" )
对于此类标志,默认值只是变量的初始值。
定义所有标志后,调用
flag . Parse ()
将命令行解析为定义的标志。
然后可以直接使用标志。如果您使用标志本身,它们都是指针;如果你绑定到变量,它们就是值。
fmt . Println ( "ip has value " , * ip )
fmt . Println ( "flagvar has value " , flagvar )
如果您有 FlagSet 但发现很难跟上代码中的所有指针,则可以使用辅助函数来获取存储在 Flag 中的值。如果您有一个 pflag.FlagSet ,其标志名为“flagname”,类型为 int,则可以使用 GetInt() 来获取 int 值。但请注意,“flagname”必须存在并且必须是 int。 GetString("flagname") 将失败。
i , err := flagset . GetInt ( "flagname" )
解析后,标志后面的参数可用作切片 flag.Args() 或单独用作 flag.Arg(i)。参数的索引从 0 到 flag.NArg()-1。
pflag 包还定义了一些 flag 中没有的新函数,它们为标志提供了一个字母的简写。您可以通过将“P”附加到定义标志的任何函数的名称来使用它们。
var ip = flag . IntP ( "flagname" , "f" , 1234 , "help message" )
var flagvar bool
func init () {
flag . BoolVarP ( & flagvar , "boolname" , "b" , true , "help message" )
}
flag . VarP ( & flagVal , "varname" , "v" , "help message" )
速记字母可以在命令行上与单破折号一起使用。布尔速记标志可以与其他速记标志组合。
默认的命令行标志集由顶级函数控制。 FlagSet 类型允许定义一组独立的标志,例如在命令行界面中实现子命令。 FlagSet 的方法类似于命令行标志集的顶级函数。
创建标志后,可以为给定标志设置 pflag.NoOptDefVal。这样做会稍微改变标志的含义。如果标志具有 NoOptDefVal 并且在命令行上设置了该标志但没有选项,则该标志将设置为 NoOptDefVal。例如给出:
var ip = flag . IntP ( "flagname" , "f" , 1234 , "help message" )
flag . Lookup ( "flagname" ). NoOptDefVal = "4321"
会导致类似的结果
解析的参数 | 结果值 |
---|---|
--标志名=1357 | ip=1357 |
--标志名 | ip=4321 |
[没有什么] | ip=1234 |
--flag // boolean flags, or flags with no option default values
--flag x // only on flags without a default value
--flag=x
与 flag 包不同,选项前的单破折号与双破折号的含义不同。单破折号表示标志的一系列简写字母。除最后一个速记字母外的所有速记字母都必须是布尔标志或具有默认值的标志
// boolean or flags where the 'no option default value' is set
-f
-f=true
-abc
but
-b true is INVALID
// non-boolean and flags without a 'no option default value'
-n 1234
-n=1234
-n1234
// mixed
-abcs "hello"
-absd="hello"
-abcs1234
标志解析在终止符“--”之后停止。与 flag 包不同,flags 可以在命令行中此终止符之前的任何位置散布参数。
整数标志接受 1234、0664、0x1234,并且可能为负数。布尔标志(长形式)接受 1、0、t、f、true、false、TRUE、FALSE、True、False。持续时间标志接受任何对 time.ParseDuration 有效的输入。
可以设置自定义标志名称“标准化函数”。它允许标志名称在代码中创建时和在命令行上使用时更改为某种“规范化”形式。 “标准化”形式用于比较。下面是使用自定义标准化函数的两个示例。
示例 #1 :您想要 -、_ 和 。在标志中进行比较相同。又名 --my-flag == --my_flag == --my.flag
func wordSepNormalizeFunc ( f * pflag. FlagSet , name string ) pflag. NormalizedName {
from := [] string { "-" , "_" }
to := "."
for _ , sep := range from {
name = strings . Replace ( name , sep , to , - 1 )
}
return pflag . NormalizedName ( name )
}
myFlagSet . SetNormalizeFunc ( wordSepNormalizeFunc )
示例#2 :您想要为两个标志起别名。又名 --old-flag-name == --new-flag-name
func aliasNormalizeFunc ( f * pflag. FlagSet , name string ) pflag. NormalizedName {
switch name {
case "old-flag-name" :
name = "new-flag-name"
break
}
return pflag . NormalizedName ( name )
}
myFlagSet . SetNormalizeFunc ( aliasNormalizeFunc )
可以弃用一个标志,或者只是它的简写。弃用标志/简写会将其隐藏在帮助文本中,并在使用弃用的标志/简写时打印使用消息。
示例#1 :您想要弃用名为“badflag”的标志,并告知用户应该使用什么标志。
// deprecate a flag by specifying its name and a usage message
flags . MarkDeprecated ( "badflag" , "please use --good-flag instead" )
这会从帮助文本中隐藏“badflag”,并打印Flag --badflag has been deprecated, please use --good-flag instead
当使用“badflag”时。
示例#2 :您希望保留标志名称“noshorthandflag”,但不推荐使用其短名称“n”。
// deprecate a flag shorthand by specifying its flag name and a usage message
flags . MarkShorthandDeprecated ( "noshorthandflag" , "please use --noshorthandflag only" )
这会在帮助文本中隐藏短名称“n”,并打印Flag shorthand -n has been deprecated, please use --noshorthandflag only
当使用简写“n”时。
请注意,使用消息在这里是必不可少的,并且不应该为空。
可以将标志标记为隐藏,这意味着它仍将正常工作,但不会显示在使用/帮助文本中。
示例:您有一个名为“secretFlag”的标志,您只需要内部使用,并且不希望它出现在帮助文本中,或者使其使用文本可用。
// hide a flag by specifying its name
flags . MarkHidden ( "secretFlag" )
pflag
允许您禁用帮助和使用消息的标志排序。
例子:
flags . BoolP ( "verbose" , "v" , false , "verbose output" )
flags . String ( "coolflag" , "yeaah" , "it's really cool flag" )
flags . Int ( "usefulflag" , 777 , "sometimes it's very useful" )
flags . SortFlags = false
flags . PrintDefaults ()
输出:
-v, --verbose verbose output
--coolflag string it's really cool flag (default "yeaah")
--usefulflag int sometimes it's very useful (default 777)
为了支持使用 Go 的flag
包定义的标志,必须将它们添加到pflag
标志集中。这通常是支持第三方依赖项(例如golang/glog
)定义的标志所必需的。
示例:您想要将 Go 标志添加到CommandLine
标志集
import (
goflag "flag"
flag "github.com/spf13/pflag"
)
var ip * int = flag . Int ( "flagname" , 1234 , "help message for flagname" )
func main () {
flag . CommandLine . AddGoFlagSet ( goflag . CommandLine )
flag . Parse ()
}
您可以在 godoc.org 上查看 pflag 包的完整参考文档,或者通过运行godoc -http=:6060
并浏览到 http://localhost:6060/pkg/github.com/spf13/pflag 通过 go 的标准文档系统查看 pflag 包的完整参考文档安装后。