首页 体育 教育 财经 社会 娱乐 军事 国内 科技 互联网 房产 国际 女人 汽车 游戏

Go 命令行解析 flag 包之快速上手

2019-12-16

开发一个指令行东西,视杂乱程度,一般要挑选一个适宜的指令行解析库,简略的需求用 Go 规范库 flag 就够了,flag 的运用十分简略。

当然,除了规范库 flag 外,也有不少的第三方库。比方,为了代替 flag 而生的 pflag ,它支撑 POSIX 风格的指令行解析。关于 POSIX 风格,本文结尾有个简略的介绍。

更多与指令行处理相关的库,能够翻开 awesome-go#command-line 指令行一节检查,star 最多的是 spf13/cobra 和 urfave/cli ,与 flag / pflag 比较,它们愈加杂乱,是一个彻底的全功能的结构。

有爱好都能够了解下。

回归主题,持续介绍 flag 吧。经过事例介绍包的运用会比较直观。

举一个比方阐明吧。假定,现在要开发一个 Go 言语环境的版别办理东西,gvg。

指令行的协助信息如下:

NAME:
 gvg - go version management by go
USAGE:
 gvg [global options] command [command options] [arguments...]
VERSION:
 0.0.1
COMMANDS:
 list list go versions
 install install a go version
 info show go version info
 use select a version
 uninstall uninstall a go version
 get get the latest code
 uninstall uninstall a go version
 help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
 --help, -h show help
 --version, -v print the version

这个指令不只包含了大局的选项,还有 8 个子指令,部分子指令支撑参数和选项。暂时,子指令的选项参数先不列出来了,完成时再看。

接下来,咱们试着经过 flag 完成这个作用。本文只介绍 GLOBAL OPTIONS的完成。

假如想了解什么是 Go 言语环境的版别办理,能够检查 怎么灵敏地进行 Go 版别办理 一文。

最简略的指令不需求任何参数和选项,杂乱一点,要支撑参数和选项的装备。gvg 没有大局参数,或者说大局参数是子指令,大局选项有 --help -h 和 --version -h 。

一个选项在 flag 包顶用一个 Flag 表明,那 -h 能够用一个 Flag 表明。一个选项一般由几个部分组成,如称号、运用阐明和默认值。假如将 -h 用代码表明,如下:

h := flag.Bool

界说了一个布尔类型的 Flag ,名为 h ,默认值是 false,运用阐明为 “show help”。变量 h 是一个布尔型的指针,经过它能够取出指令行传入的值。

除了运用 flag.Bool ,还能够运用别的一种方法界说一个 Flag 。咱们能够用这种方法界说 -v 选项。

代码如下:

var v bool
flag.BoolVar

最终的三个参数意义与 flag.Bool 相同,首要差异在值的获取方法, flag.BoolVar 是经过将变量地址传入获取值。从经历来看,第二种方法运用的较多,或许因为第一种方法会发生变量逃逸。

除了布尔类型, Flag 的类型还有整数、浮点数、字符串和时长。

假定 gvg 的事例中,支撑装备文件选项 --config-path 。完成代码如下:

var configPath
flag.StringVar

经过 StringVar 界说了新的 Flag 。运用方法与 BoolVar 相同,最终的三个参数分别是选项称号、默认值和运用阐明。

尽管 flag 支撑的内置类型并不多,但现已满意大部分需求了。假如有自界说的需求,也能够扩展新的类型完成,这部分内容下篇介绍。

现在现已完成了 -h 和 -v 两个选项,但方针是 -v --version 和 -h --help ,即一起支撑长短选项。

一个 Flag 应该有长短两种方法,但 flag 包并不支撑这种风格,需求曲线救国才干完成。

这儿以 -v --version 为例,代码如下:

flag.BoolVar
flag.BoolVar

界说了两个 Flag ,一起绑定到了一个变量上。这种作用只能用 flag.BoolVar 方法界说新的 Flag , flag.Bool 没办法做到将同一个变量一起绑定两个 Flag 。

但其实这种也有缺陷,先不说了,后边介绍协助信息打印时就理解了。

界说好一切 Flag ,还需求一步解析才干拿到正确的成果。这一步十分简略,调用 flag.Parse 即可。

如下是完好的代码:

package main
var h *bool
var v bool
func init {
 flag.BoolVar
 flag.BoolVar
 flag.BoolVar
 flag.BoolVar
func main {
 flag.Parse
 fmt.Println
 fmt.Println
}

现在就能够将它编译为 gvg 指令了。

在正式运用指令前,先介绍下 flag 的语法。官方文档阐明,指令行中 flag 选项的运用语法有如下几种方法。

-flag
-flag=x
-flag x // 非布尔类型才支撑这种方法

但其实,– 也是支撑的。因而,上面才干够完成 --version 的曲线救国。

运用下这个指令,将 help 设置为 false 和 version 设置为 true 。我尽量把一切或许的写法都列出来。

$ gvg -v
$ gvg -version -h=false # 单个 - ,即 -version 支撑
$ gvg --version=true --help=false
$ gvg --version=1 --help=0
$ gvg --version=t --help=f
$ gvg --version=T --help=F
$ gvg --version true --help true # 写法过错,因为无法识别出是 bool 值,仍是参数或子指令
$ gvg -vh # 不支撑这种风格

执行指令,输出成果:

version true
help false

到这儿,flag 的快速入门就介绍完了。参数留在子指令的时分介绍。

因为一些前史原因,Unix 呈现过许多不同的分支,指令行的风格也因而有许多规范,比方:

在网上找到一个搞笑漫画。

检查体系进程有两种写法, ps aux 和 ps -elf 。之前,我一向很抑郁为什么有这个差异。现在算是理解了。哈哈。

POSIX 的指令行风格算是扬长避短的调集吧。什么是 POSIX 风格?能够检查这篇文档 指令参数语法 。它一起供给了长短选项的规范。

要理解的是,规范毕竟仅仅规范,许多指令其实并不遵从它。但自己在规划指令行规范的时分,最好仍是要有一套规范,而参阅最一致的规范肯定是没错的。

本文介绍了 Go 中 flag 包的运用,一般的场景现已满足运用了。最终,简略地谈了一个比较趣味性的论题,指令行的风格,是否有种感觉,程序员之间的门派之争真是无处不在。

热门文章

随机推荐

推荐文章