阅读目录
- 阐述
- Golang 标准库中 flag 包的用法
- 1 参数种类
- 2 入门示例
- 3 改进一下
- 4 参数类型
- 布尔型
- 数值型
- 字符串
- 时间类型
- 长短选项
阐述
在 Golang 程序中有很多种方法来处理命令行参数。
简单的情况下可以不使用任何库,直接使用 os.Args
。
package main
import (
"fmt"
"os"
)
func main() {
//os.Args是一个[]string
if len(os.Args) > 0 {
for index, arg := range os.Args {
fmt.Printf("args[%d]=%v\n", index, arg)
}
}
}
PS E:\TEXT\test_go\test> go run .\main.go hello world hello golang
args[0]=C:\Users\ADMINI~1\AppData\Local\Temp\go-build1342876605\b001\exe\main.exe
args[1]=hello
args[2]=world
args[3]=hello
args[4]=golang
PS E:\TEXT\test_go\test>
Golang 标准库中 flag 包的用法
1 参数种类
根据参数是否为布尔型,可以分为两种:
布尔型参数:
如 --debug
,后面不用再接具体的值,指定就为 True
,不指定就为 False
非布尔型参数。
非布尔型参数:
非布尔型,有可能是 int,string
等其他类型,如 --name jack
,后面可以接具体的参数值。
根据参数名的长短,还可以分为:
长参数:
比如 --name jack
就是一个长参数,参数名前有两个 -
。
短参数:
通常为一个或两个字母(是对应长参数的简写),比如 -n
,参数名前只有一个 -
。
2 入门示例
我先用一个字符串类型的参数的示例,抛砖引玉。
package main
import (
"flag"
"fmt"
)
func main() {
var name string
flag.StringVar(&name, "name", "jack", "your name")
flag.Parse() // 解析参数
fmt.Println(name)
}
flag.StringVar
定义了一个字符串参数,它接收几个参数:
第一个参数 :
接收值后,存放在哪个变量里,需为指针。
第二个参数 :
在命令行中使用的参数名,比如 --name jack
里的 name
。
第三个参数 :
若命令行中未指定该参数值,那么默认值为 jack
。
第四个参数:
记录这个参数的用途或意义。
运行以上程序,输出如下:
PS E:\TEXT\test_go\test> go run .\main.go
jack
PS E:\TEXT\test_go\test> go run .\main.go --name wgchen
wgchen
PS E:\TEXT\test_go\test>
3 改进一下
如果你的程序只接收很少的几个参数时,上面那样写也没有什么问题。
但一旦参数数量多了以后,一大堆参数解析的代码堆积在 main 函数里,影响代码的可读性、美观性。
建议将参数解析的代码放入 init 函数中,init 函数会先于 main 函数执行。
package main
import (
"flag"
"fmt"
)
var name string
func init() {
flag.StringVar(&name, "name", "jack", "your name")
}
func main() {
flag.Parse()
fmt.Println(name)
}
4 参数类型
当你在命令行中指定了参数,Go 如何解析这个参数,转化成何种类型,是需要你事先定义的。
不同的参数,对应着 flag 中不同的方法。
下面分别讲讲不同的参数类型,都该如何定义。
布尔型
实现效果:
当不指定 --debug
时,debug
的默认值为 false
,你一指定 --debug
,debug
为赋值为 true
。
package main
import (
"flag"
"fmt"
)
var debug bool
func init() {
flag.BoolVar(&debug, "debug", false, "是否开启 DEBUG 模式")
}
func main() {
flag.Parse()
fmt.Println(debug)
}
运行后,执行结果如下:
PS E:\TEXT\test_go\test> go run .\main.go
false
PS E:\TEXT\test_go\test> go run .\main.go --debug
true
PS E:\TEXT\test_go\test>
数值型
定义一个 age 参数,不指定默认为 18。
package main
import (
"flag"
"fmt"
)
var age int
func init() {
flag.IntVar(&age, "age", 18, "你的年龄")
}
func main() {
flag.Parse()
fmt.Println(age)
}
PS E:\TEXT\test_go\test> go run .\main.go
18
PS E:\TEXT\test_go\test> go run .\main.go --age 20
20
PS E:\TEXT\test_go\test>
int64、 uint 和 float64 类型分别对应 Int64Var 、 UintVar、Float64Var 方法,也是同理,不再赘述。
字符串
定义一个 name参数,不指定默认为 jack。
package main
import (
"flag"
"fmt"
)
var name string
func init() {
flag.StringVar(&name, "name", "jack", "你的名字")
}
func main() {
flag.Parse()
fmt.Println(name)
}
运行后,执行结果如下
$ go run main.go
jack
$ go run main.go --name wangbm
wangbm
时间类型
定义一个 interval 参数,不指定默认为 1s。
package main
import (
"flag"
"fmt"
"time"
)
var interval time.Duration
func init() {
flag.DurationVar(&interval, "interval", 1*time.Second, "循环间隔")
}
func main() {
flag.Parse()
fmt.Println(interval)
}
验证效果如下
PS E:\TEXT\test_go\test> go run .\main.go
1s
PS E:\TEXT\test_go\test> go run .\main.go --interval 2s
2s
PS E:\TEXT\test_go\test>
长短选项
flag 包,在使用上,其实并没有没有长短选项之别,你可以看下面这个例子。
package main
import (
"flag"
"fmt"
)
var name string
func init() {
flag.StringVar(&name, "name", "明哥", "你的名字")
}
func main(){
flag.Parse()
fmt.Println(name)
}
$ go run main.go
明哥
$ go run main.go --name jack
jack
$ go run main.go -name jack
jack
一个 -
和两个 -
执行结果是相同的。