go的解析命令行库go-flags
Posted F3nGaoXS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go的解析命令行库go-flags相关的知识,希望对你有一定的参考价值。
简介
Go的标准库flag
由于其有不支持短选项,选项定义比较繁琐,默认只支持有限的数据类型。为了解决这些问题,出现了不少第三方解析命令行选项的库,go-flags
就是其中一个。
go-flags
提供了比标准库flag
更多的选项,它利用结构体的标签tag
和反射提供了一个方便、简洁的接口。除了基本的功能,还提供了其他丰富的特性:
-
支持短选项
-v
和长选项-verbose
-
支持短选项合写,如
-aux
-
同一选项可以设置多个值
-
支持所有基础类型和map类型,甚至函数
-
支持命名空间和选项组
等等…
快速开始
使用go get
安装第三方库
$ go get github.com/jessevdk/go-flags
快速开始
type Option struct
Names []string `short:"n" long:"name" description:"names of user"`
func main()
var opt Option
flags.Parse(&opt)
fmt.Println(opt.Names)
运行程序
$ go run main.go --name test1 --name test2 --name test3
[test1 test2 test3]
使用go-flags
的一般步骤:
- 在
struct
结构体的tag中定义选项。short
定义短选项,long
定义长选项,description
设置帮助信息。 - 声明选项变量。
- 和
flag
类似地,调用flags.Parse()
开始解析选项。
基本特性
支持丰富的数据类型
go-flags
相比标准库flag
支持更丰富的数据类型:
- 所有基本的数据类型(包括符号整数和无符号整数,浮点数,布尔类型和字符串)及它们的切片
- map类型。不过仅支持键为
string
,值为基础类型。 - 函数类型。
Tips
切片类型选项,遇到相同的选项时,值会被追加到切片中。而非切片类型选项,如果遇到相同选项,后出现的值会覆盖先出现的值。
选项是函数类型:函数类型的参数有且仅有一个,作为函数的入参。
选项是map类型:键只能是string类型,值是基本的数据类型,格式为
key:value
示例
main.go:
type Option struct
Names []string `short:"n" long:"name" description:"names of users"`
Age int `short:"a" long:"age" description:"age of user"`
Pointers []*string `short:"p" long:"pointer" description:"pointers of *string"`
Call func(int) `short:"c" long:"call" description:"call function"`
Values map[string]int `short:"v" long:"value" description:"values of user"`
func main()
var opt Option
opt.Call = func(v int)
// 预先定义好call属性的函数类型的实现,然后parse后会自动进行调用
fmt.Println("call function:", v)
if _, err := flags.Parse(&opt); err != nil
panic("flags parse failed")
fmt.Println(opt.Names)
fmt.Println(opt.Age)
for _, p := range opt.Pointers
fmt.Println(*p)
fmt.Println(opt.Values)
terminal:
$ go run main.go --name test1 -n test2 -n test3 -a 18 -a 19 -p pointer -c 18 -v k1:18
call function: 18
[test1 test2 test3]
19
pointer
map[k1:18]
常用设置
required
为true时,对应的选项必须设置值,否则会抛出ErrRequired
错误
default
用于设置选项的默认值,即选项如果没有设置值的时候,会使用此默认值
main.go
type Config struct
Name string `short:"n" required_default:"true"`
Gender string `short:"g" default:"man"`
func main()
var config Config
if _, err := flags.Parse(&config); err != nil
log.Fatal("parse failed:", err)
fmt.Println(config.Name)
fmt.Println(config.Gender)
terminal
$ go run main.go -n test
test
man
高级特性
选项分组
main.go
type Option struct
Name string `long:"name"`
Info InfoOption `group:"info"`
Contact ContactOption `group:"contact"`
type InfoOption struct
Gender bool `long:"gender"`
Age int `long:"age"`
type ContactOption struct
Email string `long:"email"`
Phone string `long:"phone"`
func main()
var opt Option
if _, err := flags.Parse(&opt); err != nil
log.Fatalln("flags parse failed:", err)
fmt.Println(opt.Name)
fmt.Println(opt.Info)
fmt.Println(opt.Contact)
将分组的选项拆分到另外两个结构体当中,并且在父结构体中使用时,加上Tag:group:""
terminal
$ go run main.go --name test --gender --age 18 --email abc@example.com --phone 1111111
test
true 18
abc@example.com 1111111
参考
以上是关于go的解析命令行库go-flags的主要内容,如果未能解决你的问题,请参考以下文章