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的一般步骤:

  1. struct结构体的tag中定义选项。short定义短选项,long定义长选项,description设置帮助信息。
  2. 声明选项变量。
  3. 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-flags

以上是关于go的解析命令行库go-flags的主要内容,如果未能解决你的问题,请参考以下文章

go的解析命令行库go-flags

go的解析命令行库flag

go的解析命令行库flag

go的解析命令行库flag

Go命令行库Cobra的核心文件root.go

Go语言---小白入门-命令行库Cobra的使用