Go语言标准库之命令行参数的解析:flag 库详解

Posted 知其黑、受其白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言标准库之命令行参数的解析:flag 库详解相关的知识,希望对你有一定的参考价值。

阅读目录

阐述

在 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,你一指定 --debugdebug 为赋值为 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

一个 - 和两个 - 执行结果是相同的。

以上是关于Go语言标准库之命令行参数的解析:flag 库详解的主要内容,如果未能解决你的问题,请参考以下文章

Go语言标准库之flag

go语言标准库之flag

小白学标准库之 flag

Go语言-获取命令行参数

14.Go语言标准库flag基本使用

go语言学习-标准库flag和log