首页 > 编程笔记 > Go语言笔记 阅读:13

Go语言flag包的用法(附带实例)

Go语言中,有时我们需要解析和处理外部传入的参数,这时可以使用 flag 包,它用于解析基本的命令行参数。

简单标记的声明方式

简单标记的声明仅支持字符串、整数和布尔值选项,定义如下:
func Int(name string, value int, usage string) *int
func String(name string, value string, usage string) *string
func Bool(name string, value bool, usage string) *bool
上述定义中参数的含义如下:
在下面的示例中,我们定义了两个命令行参数:flagInt(整型)和 flagString(字符串类型)。每个参数都有一个默认值和一个描述。使用 flag.Parse 函数解析命令行参数,解析完以后,可以通过指针访问已解析的参数值。

在下面示例中,我们输出的是解析后的参数值以及未解析的命令行参数:
func main() {
    //定义命令行参数
    var flagInt = flag.Int("p1",0,"p1接收一个int类型的参数,用于xxx")
    var flagString = flag.String("p2","下雪","p2接收一个string类型的参数,用于xxx")
   
    //解析命令行参数。这句很重要,不然传入的参数不生效
    flag.Parse()
 
    // 输出命令行参数       
    fmt.Println(*flagInt,*flagString)
    // 输出未解析的命令行参数
    fmt.Println("未解析的命令行参数:", flag.Args())
}
编译并执行上述代码,输出的值就是 flag 定义的默认值。
$ go build -o mytool main.go
$ ./mytool arg1 arg2
0 下雪
未解析的命令行参数: [arg1 arg2]

传入不存在的参数,执行时会返回错误并提示 flag 中定义的帮助信息,示例代码如下:
$ ./mytool -s
flag provided but not defined: -s
Usage of ./mytool:
  -p1 int
       p1接收一个int类型的参数,用于xxx
  -p2 string
       p2接收一个string类型的参数,用于xxx (default "下雪")

将想用的参数值传入,得到的输出如下:
$ ./mytool -p1=100 -p2 出太阳
100 出太阳
未解析的命令行参数: []

其他使用方式

除了声明简单标记,flag 包还有更复杂的使用方式,具体如下。

1) 自定义标记

flag.Value 是一个接口,它定义了解析和设置命令行参数的方法。如果想创建一个自定义类型的命令行参数,只需实现 flag.Value 接口的方法集即可。

下面是 flag.Value 接口的定义:
type Value interface {
    String() string
    Set(string) error
}

2) 绑定标记的声明方式

flag 包中的 intValue、stringValue 等类型实现了 Value 接口,这意味着它们可以作为命令行参数使用。

用程序中已有的参数来声明一个标志,示例代码如下:
var intValue int
flag.IntVar(&intValue,"p3",-1,"p3绑定了一个int类型的参数")

3) 修改帮助信息的方法

在使用工具时,如果输入 -h 选项,程序会输出已定义好的帮助信息,这实际上是通过调用 flag.Usage 函数来实现的。

我们可以修改 flag.Usage 函数,让其显示我们想要的帮助信息。示例代码如下:
flag.Usage = func() {
    fmt.Fprintf(os.Stderr,"mytool version: v0.1 Usage: mytool [-p1] [-p2] [-h]" )
    flag.PrintDefaults()
}

4) flag.Args函数

os.Args 是一个字符串切片,它保存了从命令行中传递给程序的所有参数。os.Args[0] 是程序的名称,os.Args[1:] 是程序接收的实际参数。

flag.Args 函数用于返回未被解析的命令行参数,也就是那些未被 flag 包识别为已声明命令行选项的参数。相比 os.Args,flag.Args函数可以更方便地处理命令行参数,因为它已经解析了选项以及与选项对应的值,只留下了那些未被解析的参数。

另外,也可使用 flag.NArg 函数获取传入参数的个数。

相关文章