Golang 中Args和Flag 使用

920 阅读2分钟

创建命令行程序时,可以有两种方式在程序运行时获取到传递给程序的参数,分别就是:args 和 flag

Args

os.Args 就是获取程序运行时传递给程序的参数,在程序中可直接通过os.Args获取得到,如下:

package main
​
import (
    "fmt"
    "os"
)
​
func main() {
    for _,v := range os.Args{
        fmt.Println(v)
    }
}
​
// 运行结果
go run main.go 1 2 3
/tmp/go-build1601777560/b001/exe/main
1
2
3

由此可知,os.Args就是一个字符数组[]string,它的第一个索引值是可执行程序的路径,后面的索引值就是在程序运行时传递给程序的参数了,各个参数之间按照空格分隔开,它会自动省略两个字串之间多余的空格

flag

golang 在标准库中提供了一个功能更加丰富的处理命令行参数的工具包:flag,相比较于 os.Args它能更加精确的获取得到每一个类型的值,下面举个例子

package main
​
import (
    "flag"
    "fmt"
)
​
// version 是传递的 key,3.0.2 是默认值,最后的就是用例说明
var version = flag.String("version","3.0.2","This is app version")
​
func main() {
    var name string
    flag.StringVar(&name,"name","tst","This is app name")
    flag.Parse()
​
    fmt.Println(*version)
    fmt.Println(name)
}
​
// 运行结果
go run main.go --version=1.0.2 -name=12
1.0.2
12

上面有两种获取flag的方式:

  • 第一种就是直接将flag赋值给了一个变量,flag.String返回的类型是指针,所以在使用的使用需要通过*version获取
  • 第二种方式,就是声明一个变量,然后将变量的地址传递进去,这样使用的时候直接使用变量就可以了

flag.Parse()就是解析上面定义的所有flag到对应的变量上面,如果不解析的话就会使用指定的默认值

注:如果需要被 flag解析,那么传入的参数必须以--或者-开头,否则是不会被解析的

flag.Args()

上面程序运行时传入的都是flag可以解析的值,也就是在程序中提前定义过的;那如果在命令行参数中出现了不能够解析的值,怎么办呢?

答案就是使用flag.Args(),它就会获取所有不能被解析的值,如下例子:

package main
​
import (
    "flag"
    "fmt"
)
​
var version = flag.String("version","3.0.2","This is app version")
​
func main() {
    var name string
    flag.StringVar(&name,"name","tst","This is app name")
    flag.Parse()
​
    fmt.Println(*version)
    fmt.Println(name)
​
    for _,v := range flag.Args(){
        fmt.Println(v)
    }
}
​
//运行结果
go run main.go --version=1.0.2 -name=12 cca aa
1.0.2
12
cca
aa

当然,如果命令行参数后的第一个值就不能被解析,那么就会把所有的值全部当作flag.Args,即便存在可以解析的值,也不会再解析,如下:

go run main.go pp --version=1.0.2 -name=12 cca aa
3.0.2
tst
pp
--version=1.0.2
-name=12
cca
aa