<p>评论有人提到没有例子,不知道讲的是什么。因此,为了大家能够更好地理解,特意加了一个示例。其实本文更多讲解的是 flag 的实现原理,加上示例之后,就更好地知道怎么使用了。建议阅读 《Go语言标准库》一书的对应章节:<a href="http://books.studygolang.com/The-Golang-Standard-Library-by-Example/chapter13/13.1.html">flag – 命令行参数解析</a>。</p>
<p>在写命令行程序(工具、server)时,对命令参数进行解析是常见的需求。各种语言一般都会提供解析命令行参数的方法或库,以方便程序员使用。如果命令行参数纯粹自己写代码解析,对于比较复杂的,还是挺费劲的。在go标准库中提供了一个包:flag,方便进行命令行解析。</p>
<p>注:区分几个概念<br> 1)命令行参数(或参数):是指运行程序提供的参数<br> 2)已定义命令行参数:是指程序中通过flag.Xxx等这种形式定义了的参数<br> 3)非flag(non-flag)命令行参数(或保留的命令行参数):后文解释</p>
<h2>一、使用示例</h2>
<p>我们以 nginx 为例,执行 nginx -h,输出如下:</p>
<pre class="blockcode"><code class="language-bash">nginx version: nginx/1.10.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /usr/local/nginx/)
-c filename : set configuration file (default: conf/nginx.conf)
-g directives : set global directives out of configuration file
</code></pre>
<p> </p>
<p> </p>
<p>我们通过 `flag` 实现类似 nginx 的这个输出,创建文件 nginx.go,内容如下:</p>
<pre class="blockcode"><code class="language-Go">package main
import (
"flag"
"fmt"
"os"
)
// 实际中应该用更好的变量名
var (
h bool
v, V bool
t, T bool
q *bool
s string
p string
c string
g string
)
func init() {
flag.BoolVar(&h, "h", false, "this help")
flag.BoolVar(&v, "v", false, "show version and exit")
flag.BoolVar(&V, "V", false, "show version and configure options then exit")
flag.BoolVar(&t, "t", false, "test configuration and exit")
flag.BoolVar(&T, "T", false, "test configuration, dump it and exit")
// 另一种绑定方式
q = flag.Bool("q", false, "suppress non-error messages during configuration testing")
// 注意 `signal`。默认是 -s string,有了 `signal` 之后,变为 -s signal
flag.StringVar(&s, "s", "", "send `signal` to a master process: stop, quit, reopen, reload")
flag.StringVar(&p, "p", "/usr/local/nginx/", "set `prefix` path")
flag.StringVar(&c, "c", "conf/nginx.conf", "set configuration `file`")
flag.StringVar(&g, "g", "conf/nginx.conf", "set global `directives` out of configuration file")
// 改变默认的 Usage
flag.Usage = usage
}
func main() {
flag.Parse()
if h {
flag.Usage()
}
}
func usage() {
fmt.Fprintf(os.Stderr, `nginx version: nginx/1.10.0
Usage: nginx [-hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
`)
flag.PrintDefaults()
}</code></pre>
<p><br> 在flag包中,进行了进一步封装:将FlagSet的方法都重新定义了一遍,也就是提供了一序列函数,而函数中只是简单的调用已经实例化好了的FlagSet实例:commandLine 的方法,这样commandLine实例便不需要export。这样,使用者是这么调用:flag.Parse()而不是flag.commandLine.Parse()。(Go 1.2 版本起改为了 CommandLine)执行:go run nginx.go -h,(或 go build -o nginx && ./nginx -h)输出如下:</p>
<pre class="blockcode"><code class="language-bash">nginx version: nginx/1.10.0
Usage: nginx [-hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
-T test configuration, dump it and exit
-V show version and configure options then exit
-c file
set configuration file (default "conf/nginx.conf")
-g directives
set global directives out of configuration file (default "conf/nginx.conf")
-h this help
-p prefix
set prefix path (default "/usr/local/nginx/")
-q suppress non-error messages during configuration testing
-s signal
send signal to a master process: stop, quit, reopen, reload
-t test configuration and exit
-v show version and exit</code></pre>
<p>仔细理解以上例子,如果有不理解的,看完下文的讲解再回过头来看。</p>
<h2>二、flag包概述</h2>
<p>flag包实现了命令行参数的解析 |
|