go-arg

go-arg

Go 语言结构体驱动的命令行参数解析库

go-arg 是一个基于结构体的 Go 语言命令行参数解析库。开发者可通过定义结构体来声明程序的命令行参数,支持必需参数、位置参数、环境变量和默认值等功能。该库还提供自定义验证、版本字符串和子命令等特性,适用于构建简单到复杂的命令行接口。go-arg 设计简洁,易于集成,适合各种规模的 Go 项目使用。

go-arg命令行参数解析Go语言结构体子命令Github开源项目
<h1 align="center"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/785d2e30-2e49-479a-9c04-62cde197c186.jpg" alt="go-arg" height="250px"> <br> go-arg </br> </h1> <h4 align="center">基于结构体的Go语言参数解析</h4> <p align="center"> <a href="https://sourcegraph.com/github.com/alexflint/go-arg?badge"><img src="https://yellow-cdn.veclightyear.com/2b54e442/5f094cc7-4765-4ec6-9b65-10d00975f577.svg" alt="Sourcegraph"></a> <a href="https://pkg.go.dev/github.com/alexflint/go-arg"><img src="https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square" alt="文档"></a> <a href="https://github.com/alexflint/go-arg/actions"><img src="https://yellow-cdn.veclightyear.com/2b54e442/f1628288-0149-49da-9e12-1e9d830ab555.svg" alt="构建状态"></a> <a href="https://codecov.io/gh/alexflint/go-arg"><img src="https://yellow-cdn.veclightyear.com/2b54e442/e2b60990-5ea6-4973-85ec-8719a4a0119b.svg" alt="覆盖率状态"></a> <a href="https://goreportcard.com/report/github.com/alexflint/go-arg"><img src="https://goreportcard.com/badge/github.com/alexflint/go-arg" alt="Go报告卡"></a> </p> <br>

通过定义结构体来声明程序的命令行参数。

var args struct { Foo string Bar bool } arg.MustParse(&args) fmt.Println(args.Foo, args.Bar)
$ ./example --foo=hello --bar hello true

安装

go get github.com/alexflint/go-arg

必需参数

var args struct { ID int `arg:"required"` Timeout time.Duration } arg.MustParse(&args)
$ ./example 用法: example --id ID [--timeout TIMEOUT] 错误: --id 是必需的

位置参数

var args struct { Input string `arg:"positional"` Output []string `arg:"positional"` } arg.MustParse(&args) fmt.Println("输入:", args.Input) fmt.Println("输出:", args.Output)
$ ./example src.txt x.out y.out z.out
输入: src.txt
输出: [x.out y.out z.out]

环境变量

var args struct { Workers int `arg:"env"` } arg.MustParse(&args) fmt.Println("工作线程:", args.Workers)
$ WORKERS=4 ./example
工作线程: 4
$ WORKERS=4 ./example --workers=6
工作线程: 6

你也可以覆盖环境变量的名称:

var args struct { Workers int `arg:"env:NUM_WORKERS"` } arg.MustParse(&args) fmt.Println("工作线程:", args.Workers)
$ NUM_WORKERS=4 ./example
工作线程: 4

你可以使用CSV(RFC 4180)格式提供多个值:

var args struct { Workers []int `arg:"env"` } arg.MustParse(&args) fmt.Println("工作线程:", args.Workers)
$ WORKERS='1,99' ./example
工作线程: [1 99]

你还可以使用与参数名不匹配的环境变量:

var args struct { Workers int `arg:"--count,env:NUM_WORKERS"` } arg.MustParse(&args) fmt.Println("工作线程:", args.Workers)
$ NUM_WORKERS=6 ./example
工作线程: 6
$ NUM_WORKERS=6 ./example --count 4
工作线程: 4

使用说明字符串

var args struct { Input string `arg:"positional"` Output []string `arg:"positional"` Verbose bool `arg:"-v,--verbose" help:"详细程度"` Dataset string `help:"使用的数据集"` Optimize int `arg:"-O" help:"优化级别"` } arg.MustParse(&args)
$ ./example -h 用法: [--verbose] [--dataset DATASET] [--optimize OPTIMIZE] [--help] INPUT [OUTPUT [OUTPUT ...]] 位置参数: INPUT OUTPUT 选项: --verbose, -v 详细程度 --dataset DATASET 使用的数据集 --optimize OPTIMIZE, -O OPTIMIZE 优化级别 --help, -h 打印此帮助信息

默认值

var args struct { Foo string `default:"abc"` Bar bool } arg.MustParse(&args)

默认值(v1.2之前)

var args struct { Foo string Bar bool } arg.Foo = "abc" arg.MustParse(&args)

结合命令行选项、环境变量和默认值

你可以结合使用命令行参数、环境变量和默认值。命令行参数优先于环境变量,环境变量优先于默认值。这意味着我们首先检查某个选项是否在命令行上提供,如果没有,我们检查环境变量(仅当提供了env标签时),如果仍未找到,我们检查包含默认值的default标签。

var args struct { Test string `arg:"-t,env:TEST" default:"something"` } arg.MustParse(&args)

忽略环境变量和/或默认值

通过忽略环境变量和/或默认值,可以保持现有结构中的值不变。

var args struct { Test string `arg:"-t,env:TEST" default:"something"` } p, err := arg.NewParser(arg.Config{ IgnoreEnv: true, IgnoreDefault: true, }, &args) err = p.Parse(os.Args)

具有多个值的参数

var args struct { Database string IDs []int64 } arg.MustParse(&args) fmt.Printf("从%s获取以下ID: %q", args.Database, args.IDs)
./example -database foo -ids 1 2 3 从foo获取以下ID: [1 2 3]

可以多次指定的参数,与位置参数混合使用

var args struct { Commands []string `arg:"-c,separate"` Files []string `arg:"-f,separate"` Databases []string `arg:"positional"` } arg.MustParse(&args)
./example -c cmd1 db1 -f file1 db2 -c cmd2 -f file2 -f file3 db3 -c cmd3 命令: [cmd1 cmd2 cmd3] 文件: [file1 file2 file3] 数据库: [db1 db2 db3]

具有键和值的参数

var args struct { UserIDs map[string]int } arg.MustParse(&args) fmt.Println(args.UserIDs)
./example --userids john=123 mary=456 map[john:123 mary:456]

自定义验证

var args struct { Foo string Bar string } p := arg.MustParse(&args) if args.Foo == "" && args.Bar == "" { p.Fail("你必须提供--foo或--bar") }
./example 用法: samples [--foo FOO] [--bar BAR] 错误: 你必须提供--foo或--bar

版本字符串

type args struct { ... } func (args) Version() string { return "someprogram 4.3.0" } func main() { var args args arg.MustParse(&args) }
$ ./example --version someprogram 4.3.0

注意 如果在args或任何子命令中定义了--version标志,它将覆盖内置的版本控制。

覆盖选项名称

var args struct { Short string `arg:"-s"` Long string `arg:"--custom-long-option"` ShortAndLong string `arg:"-x,--my-option"` OnlyShort string `arg:"-o,--"` } arg.MustParse(&args)
$ ./example --help 用法: example [-o ONLYSHORT] [--short SHORT] [--custom-long-option CUSTOM-LONG-OPTION] [--my-option MY-OPTION] 选项: --short SHORT, -s SHORT --custom-long-option CUSTOM-LONG-OPTION --my-option MY-OPTION, -x MY-OPTION -o ONLYSHORT --help, -h 显示此帮助并退出

嵌入式结构体

嵌入式结构体的字段与常规字段一样处理:

type DatabaseOptions struct { Host string Username string Password string } type LogOptions struct { LogFile string Verbose bool } func main() { var args struct { DatabaseOptions LogOptions } arg.MustParse(&args) }

如常,任何标记为arg:"-"的字段都会被忽略。

支持的类型

以下类型可以用作参数:

  • 内置整数类型:int, int8, int16, int32, int64, byte, rune
  • 内置浮点类型:float32, float64
  • 字符串
  • 布尔值
  • 表示为url.URL的URL
  • 表示为time.Duration的时间持续
  • 表示为mail.Address的电子邮件地址
  • 表示为net.HardwareAddr的MAC地址
  • 以上任何类型的指针
  • 以上任何类型的切片
  • 使用以上任何类型作为键和值的映射
  • 任何实现encoding.TextUnmarshaler的类型

自定义解析

实现encoding.TextUnmarshaler来定义你自己的解析逻辑。

// 接受形如"head.tail"的命令行参数 type NameDotName struct { Head, Tail string } func (n *NameDotName) UnmarshalText(b []byte) error { s := string(b) pos := strings.Index(s, ".") if pos == -1 { return fmt.Errorf("在 %s 中缺少句点", s) } n.Head = s[:pos] n.Tail = s[pos+1:] return nil } func main() { var args struct { Name NameDotName } arg.MustParse(&args) fmt.Printf("%#v\n", args.Name) }
$ ./example --name=foo.bar main.NameDotName{Head:"foo", Tail:"bar"} $ ./example --name=oops 用法: example [--name NAME] 错误: 处理 --name 时出错: 在 "oops" 中缺少句点

带默认值的自定义解析

实现 encoding.TextMarshaler 来定义你自己的默认值字符串:

// 接受形如 "head.tail" 的命令行参数 type NameDotName struct { Head, Tail string } func (n *NameDotName) UnmarshalText(b []byte) error { // 与前一个例子相同 } // 只有当你想在使用说明中显示默认值时才需要这个 func (n *NameDotName) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("%s.%s", n.Head, n.Tail)), nil } func main() { var args struct { Name NameDotName `default:"file.txt"` } arg.MustParse(&args) fmt.Printf("%#v\n", args.Name) }
$ ./example --help 用法: test [--name NAME] 选项: --name NAME [默认值: file.txt] --help, -h 显示此帮助信息并退出 $ ./example main.NameDotName{Head:"file", Tail:"txt"}

自定义占位符

在1.3.0版本中引入

使用 placeholder 标签来控制在使用说明中使用的占位符文本。

var args struct { Input string `arg:"positional" placeholder:"SRC"` Output []string `arg:"positional" placeholder:"DST"` Optimize int `arg:"-O" help:"优化级别" placeholder:"LEVEL"` MaxJobs int `arg:"-j" help:"最大同时作业数" placeholder:"N"` } arg.MustParse(&args)
$ ./example -h 用法: example [--optimize LEVEL] [--maxjobs N] SRC [DST [DST ...]] 位置参数: SRC DST 选项: --optimize LEVEL, -O LEVEL 优化级别 --maxjobs N, -j N 最大同时作业数 --help, -h 显示此帮助信息并退出

描述字符串

通过实现返回字符串的 Description 函数,可以在帮助文本顶部添加描述性消息。

type args struct { Foo string } func (args) Description() string { return "该程序执行这个和那个" } func main() { var args args arg.MustParse(&args) }
$ ./example -h 该程序执行这个和那个 用法: example [--foo FOO] 选项: --foo FOO --help, -h 显示此帮助信息并退出

类似地,通过实现 Epilogue 函数,可以在帮助文本末尾添加结语。

type args struct { Foo string } func (args) Epilogue() string { return "更多信息请访问 github.com/alexflint/go-arg" } func main() { var args args arg.MustParse(&args) }
$ ./example -h 用法: example [--foo FOO] 选项: --foo FOO --help, -h 显示此帮助信息并退出 更多信息请访问 github.com/alexflint/go-arg

子命令

在1.1.0版本中引入

子命令常用于将多个功能分组到单个程序中的工具。一个例子是 git 工具:

$ git checkout [特定于检出代码的参数] $ git commit [特定于提交的参数] $ git push [特定于推送的参数]

"checkout"、"commit" 和 "push" 这些字符串与简单的位置参数不同,因为用户可用的选项会根据他们选择的子命令而改变。

这可以在 go-arg 中如下实现:

type CheckoutCmd struct { Branch string `arg:"positional"` Track bool `arg:"-t"` } type CommitCmd struct { All bool `arg:"-a"` Message string `arg:"-m"` } type PushCmd struct { Remote string `arg:"positional"` Branch string `arg:"positional"` SetUpstream bool `arg:"-u"` } var args struct { Checkout *CheckoutCmd `arg:"subcommand:checkout"` Commit *CommitCmd `arg:"subcommand:commit"` Push *PushCmd `arg:"subcommand:push"` Quiet bool `arg:"-q"` // 这个标志对所有子命令都是全局的 } arg.MustParse(&args) switch { case args.Checkout != nil: fmt.Printf("请求检出分支 %s\n", args.Checkout.Branch) case args.Commit != nil: fmt.Printf("请求提交,消息为 \"%s\"\n", args.Commit.Message) case args.Push != nil: fmt.Printf("请求从 %s 推送到 %s\n", args.Push.Branch, args.Push.Remote) }

使用子命令时还有一些额外的规则:

  • subcommand 标签只能用于指向结构体的指针字段
  • 包含子命令的任何结构体都不能包含任何位置参数

这个包允许程序接受子命令,但在没有指定子命令时也可以执行其他操作。 另一方面,如果你希望在没有指定子命令时程序终止,推荐的方式是:

p := arg.MustParse(&args) if p.Subcommand() == nil { p.Fail("缺少子命令") }

API 文档

https://godoc.org/github.com/alexflint/go-arg

原理

Go 有很多命令行参数解析库,包括标准库中的一个,那为什么还要构建另一个呢?

标准库中的 flag 库对我来说似乎有些尴尬。位置参数必须在选项之前,所以 ./prog x --foo=1 会如你所期望的那样工作,但 ./prog --foo=1 x 则不会。它也不允许参数同时具有长格式(--foo)和短格式(-f)。

许多第三方参数解析库非常适合编写复杂的命令行界面,但对于一个只有几个标志的简单脚本来说,对我而言感觉有些过度。

go-arg 背后的想法是,Go 已经有了一种使用结构体描述数据结构的优秀方式,所以没有必要开发额外的抽象层次。go-arg 用单个结构体替代了指定程序接受哪些参数的 API 和获取这些参数值的另一个 API。

向后兼容性说明

此库的早期版本要求帮助文本是 arg 标签的一部分。这仍然受支持,但现在已被弃用。相反,你应该使用上面描述的单独的 help 标签,这消除了你可以编写的文本的大部分限制。特别是,如果你的帮助文本包含任何逗号,你将需要使用新的 help 标签。

编辑推荐精选

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

下拉加载更多