Golang : pflag 包简介
笔者在前文中介绍了 Golang 标准库中 flag 包的用法,事实上有一个第三方的命令行参数解析包 pflag 比 flag 包使用的更为广泛。pflag 包的设计目的就是替代标准库中的 flag 包,因此它具有更强大的功能并且与标准的兼容性更好。本文将介绍 pflag 包与 flag 包相比的主要优势,如果你还不了解 flag 包的的用法,请参考《Golang : flag 包简介》一文。本文的演示环境为 ubuntu 18.04。 pflag 包的主要特点pflag 包与 flag 包的工作原理甚至是代码实现都是类似的,下面是 pflag 相对 flag 的一些优势:
安装 pflag 包本文介绍 doker 源代码中引用的 pflag 包 github.com/spf13/pfla,用下面的命令安装该包: $ go get github.com/spf13/pflag 入门 demo在 Go workspace 的 src 目录下创建 pflagdemo 目录,并在目录下创建 main.go 文件,编辑其内容如下: package main import flag "github.com/spf13/pflag" import ( "fmt" "strings" ) // 定义命令行参数对应的变量 var cliName = flag.StringP("name","n","nick","Input Your Name") var cliAge = flag.IntP("age","a",22,"Input Your Age") var cliGender = flag.StringP("gender","g","male","Input Your Gender") var cliOK = flag.BoolP("ok","o",false,"Input Are You OK") var cliDes = flag.StringP("des-detail","d","","Input Description") var cliOldFlag = flag.StringP("badflag","b","just for test","Input badflag") func wordSepNormalizeFunc(f *flag.FlagSet,name string) flag.NormalizedName { from := []string{"-","_"} to := "." for _,sep := range from { name = strings.Replace(name,sep,to,-1) } return flag.NormalizedName(name) } func main() { // 设置标准化参数名称的函数 flag.CommandLine.SetNormalizeFunc(wordSepNormalizeFunc) // 为 age 参数设置 NoOptDefVal flag.Lookup("age").NoOptDefVal = "25" // 把 badflag 参数标记为即将废弃的,请用户使用 des-detail 参数 flag.CommandLine.MarkDeprecated("badflag","please use --des-detail instead") // 把 badflag 参数的 shorthand 标记为即将废弃的,请用户使用 des-detail 的 shorthand 参数 flag.CommandLine.MarkShorthandDeprecated("badflag","please use -d instead") // 在帮助文档中隐藏参数 gender flag.CommandLine.MarkHidden("badflag") // 把用户传递的命令行参数解析为对应变量的值 flag.Parse() fmt.Println("name=",*cliName) fmt.Println("age=",*cliAge) fmt.Println("gender=",*cliGender) fmt.Println("ok=",*cliOK) fmt.Println("des=",*cliDes) } 代码本身很简单,也添加了注释,这里就不再过多的解释了。 运行 demo在 flagdemo 目录下执行 go build 命令编译 demo 生成可执行文件 flagdemo。下面我们通过运行 demo 程序来了解 pflag 包命令行参数的语法特点。 布尔类型的参数 --flag // 等同于 --flag=true --flag=value --flag value // 这种写法只有在没有设置默认值时才生效 NoOptDefVal 用法 var cliAge = flag.IntP("age","Input Your Age") flag.Lookup("age").NoOptDefVal = "25" 下面是传递参数的方式和参数最终的取值: Parsed Arguments Resulting Value --age=30 cliAge=30 --age cliAge=25 [nothing] cliAge=22 shorthand -o -o=true // 注意,下面的写法是不正确的 -o true 非布尔类型的参数和没有设置 NoOptDefVal 的参数的写法如下: -g female -g=female -gfemale 日常的使用中一般会混合上面的两类规则: -aon "jack" -aon="jack" -aon"jack" -aonjack -oa=35 注意 -- 后面的参数不会被解析: -oa=35 -- -gfemale
标准化参数的名称 func wordSepNormalizeFunc(f *flag.FlagSet,-1) } return flag.NormalizedName(name) } flag.CommandLine.SetNormalizeFunc(wordSepNormalizeFunc) 下面的写法也能正确设置参数了: --des_detail="person detail" 把参数标记为即将废弃 // 把 badflag 参数标记为即将废弃的,请用户使用 des-detail 参数 flag.CommandLine.MarkDeprecated("badflag","please use --des-detail instead") // 把 badflag 参数的 shorthand 标记为即将废弃的,请用户使用 des-detail 的 shorthand 参数 flag.CommandLine.MarkShorthandDeprecated("badflag","please use -d instead") 在帮助文档中隐藏参数 // 在帮助文档中隐藏参数 badflag flag.CommandLine.MarkHidden("badflag") 看,帮助文档中没有显示 badflag 的信息。其实在把参数标记为废弃时,同时也会设置隐藏参数。 总结正如本文中介绍的,pflag 包提供了很多非常棒的功能,这些功能方便了应用程序的开发者。因此越来越多的使用者抛弃标准库中的 flag 包转而使用 pflag 包解析命令行参数。 参考: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |