go的解析命令行库go-flags

12 篇文章 0 订阅

简介

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值