对flag包的理解
对于flag包的用法,go的官方文档是这么说的:flag包实现了命令行参数的解析
这句话怎么理解?什么叫实现了命令行参数的解析?看了很多博客和文档,大多数都是直接介绍包里函数的用法,但是我还是不理解它是干什么的,怎么就对命令行参数解析了?
作为一个go小白,带着这个困扰了我很久的问题开始了寻找答案的过程
解析命令行参数
大家都知道在编译go项目时用到了一个命令go build
而有时候需要对编译后的项目进行重命名,这个时候后用到一个参数-o
例如:go build -o client.exe main.go
这里对main.go函数进行编译,并把编译后的文件命名为clinet.exe
在这个过程我们使用的一个参数-o
就是命令行参数,只不过这个参数是go语言自己定义的,我们可以直接使用
那么,我们可以定义类型的命令行参数吗?当然可以——使用flag包,看到这里是不是对flag包实现了命令行参数的解析这句话突然理解了,就是让程序读懂我们在命令行附加的参数。
flag包的工作流程
基本分为三步:
- 注册flag,主要用flag.String(), Bool(), Int()等函数注册flag,或者用flag.BoolVar(),StringVar(),IntVar()等函数把flag绑定到变量,这里注册的flag就是下面的flag结构体
- 解析flag,使用flag.Parse()函数解析在命令行使用了的flag。
- 最后根据命令行输入的flag处理逻辑
flag包中的一个结构体,type Flag的定义
type Flag struct {
Name string // flag在命令行中的名字
Usage string // 帮助信息
Value Value // 要设置的值
DefValue string // 默认值(文本格式),用于使用信息
}
一个函数
这里我们找一个flag包里的函数进行解释
func StringVar
func StringVar(p *string, name string, value string, usage string)
StringVar用指定的名称、默认值、使用信息注册一个string类型flag,并将flag的值保存到p指向的变量。
注册之后,调用:
flag.Parse()
flag.Parse()来解析命令行参数写入注册的flag里。解析之后,flag的值可以直接使用。如果你使用的是flag自身,它们是指针;如果你绑定到了某个变量,它们是值。
上代码
func main() {
var user string
var pwd string
var ip string
var port string
//使用一个指针user来接受注册的flag,参数 u 是flag在命令行中的名字,类比go build -o 的-o
//下一个参数是默认值,最后一个参数是帮助信息
flag.StringVar(&user, "u", "", "user默认值是空")
flag.StringVar(&pwd, "p", "123", "密码默认为123")
flag.StringVar(&ip, "ip", "localhost", "ip默认为localhost")
flag.StringVar(&port, "port", "3306", "端口默认为3306")
//解析flag
flag.Parse()
fmt.Printf("用户名:%v\n", user)
fmt.Printf("密码:%v\n", pwd)
fmt.Printf("ip地址: %v\n", ip)
fmt.Printf("端口:%v\n", port)
}
运行结果
$ go run main.go
用户名:
密码:123
ip地址: localhost
端口:3306
//可以看出不指定参数的时候,参数的值都为默认值
$ go run main.go -u "chen" -p "pass" -ip "127.0.0.1" -port "8888"
用户名:chen
密码:pass
ip地址: 127.0.0.1
端口:8888
// 运行go run命令指定参数后,参数的值都为所指定的值