当前位置: 首页 > news >正文

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

相关文章:

  • 让所有GUI都自动化-PyAutoGUI(GUI自动化工具)
  • 备份系统运行数据采集及分析方法
  • java ssm教师工作量统计系统
  • 关于内存条的知识要点⑴
  • 银行数据中心绿色发展新格局:建设全闪数据中心
  • Java毕业设计-会议室预约小程序系统
  • 一文搞定Linux的定时器(19)
  • 物联网的常用几种协议
  • URDMA跑起来
  • 商业银行云模式下的技术变革
  • go的解析命令行库flag
  • idea jsp文件 高亮_有了这几款idea插件后,同事再也不叫我小白了
  • 猿创征文|Mybatis注解完成增删改查操作
  • Code For Better ---- 拥抱TensorFlow 拥抱未来
  • 【SpringBoot】SpringBoot自定义banner,成千上万种可供选择,当然也可以自定义生成哦
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • Apache Pulsar 2.1 重磅发布
  • Apache Spark Streaming 使用实例
  • java多线程
  • Mithril.js 入门介绍
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • 大整数乘法-表格法
  • 分布式事物理论与实践
  • 后端_MYSQL
  • 今年的LC3大会没了?
  • 前端工程化(Gulp、Webpack)-webpack
  • 算法系列——算法入门之递归分而治之思想的实现
  • 我的面试准备过程--容器(更新中)
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (12)Linux 常见的三种进程状态
  • (floyd+补集) poj 3275
  • (二)丶RabbitMQ的六大核心
  • (六)激光线扫描-三维重建
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET CLR Hosting 简介
  • .NET DataGridView数据绑定说明
  • .Net Redis的秒杀Dome和异步执行
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .net分布式压力测试工具(Beetle.DT)
  • .NET委托:一个关于C#的睡前故事
  • .NET序列化 serializable,反序列化
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [android]-如何在向服务器发送request时附加已保存的cookie数据
  • [Apio2012]dispatching 左偏树
  • [C#]winform部署yolov9的onnx模型
  • [C++]类和对象【上篇】