导入flag包

  1. import flag

flag参数类型

flag包支持的命令行参数类型有boolintint64uintuint64float float64stringduration

flag参数 有效值
字符串flag 合法字符串
整数flag 1234、0664、0x1234等类型,也可以是负数。
浮点数flag 合法浮点数
bool类型flag 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False。
时间段flag 任何合法的时间段字符串。如”300ms”、”-1.5h”、”2h45m”。
合法的单位有”ns”、”us” /“µs”、”ms”、”s”、”m”、”h”。

定义命令行flag参数

有以下两种常用的定义命令行flag参数的方法。

flag.Type()

基本格式如下:
flag.Type(flag名, 默认值, 帮助信息)*Type 例如我们要定义姓名、年龄、婚否三个命令行参数,我们可以按如下方式定义:

  1. name := flag.String("name", "张三", "姓名")
  2. age := flag.Int("age", 18, "年龄")
  3. married := flag.Bool("married", false, "婚否")
  4. delay := flag.Duration("d", 0, "时间间隔")

需要注意的是,此时nameagemarrieddelay均为对应类型的指针。

flag.TypeVar()

基本格式如下: flag.TypeVar(Type指针, flag名, 默认值, 帮助信息) 例如我们要定义姓名、年龄、婚否三个命令行参数,我们可以按如下方式定义:

  1. var name string
  2. var age int
  3. var married bool
  4. var delay time.Duration
  5. flag.StringVar(&name, "name", "张三", "姓名")
  6. flag.IntVar(&age, "age", 18, "年龄")
  7. flag.BoolVar(&married, "married", false, "婚否")
  8. flag.DurationVar(&delay, "d", 0, "时间间隔")

flag.Parse()

通过以上两种方法定义好命令行flag参数后,需要通过调用flag.Parse()来对命令行参数进行解析。
支持的命令行参数格式有以下几种:

  • -flag xxx (使用空格,一个-符号)
  • --flag xxx (使用空格,两个-符号)
  • -flag=xxx (使用等号,一个-符号)
  • --flag=xxx (使用等号,两个-符号)

其中,布尔类型的参数必须使用等号的方式指定。
Flag解析在第一个非flag参数(单个”-“不是flag参数)之前停止,或者在终止符”–“之后停止。

flag其他函数

  1. flag.Args() ////返回命令行参数后的其他参数,以[]string类型
  2. flag.NArg() //返回命令行参数后的其他参数个数
  3. flag.NFlag() //返回使用的命令行参数个数

子命令的使用

  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. )
  6. func main(){
  7. var name string
  8. flag.Parse()
  9. goCmd := flag.NewFlagSet("go",flag.ExitOnError)
  10. goCmd.StringVar(&name,"name","Go语言","帮助信息")
  11. phpCmd := flag.NewFlagSet("php",flag.ExitOnError)
  12. phpCmd.StringVar(&name,"n","php语言","帮助信息")
  13. args := flag.Args()
  14. if len(args) <= 0{
  15. return
  16. }
  17. switch args[0] {
  18. case "go":
  19. _ = goCmd.Parse(args[1:])
  20. fmt.Println("go......")
  21. case "php":
  22. _ = phpCmd.Parse(args[1:])
  23. fmt.Println("php......")
  24. }
  25. fmt.Println(name)
  26. }

由于需要处理子命令,因此调用了flag.NewFlagSet方法。该方法会返回带有指定名称和错误处理属性的空命令集,相当于创建一个新的命令集去支持子命令。需要注意的是,flag.NewFlagSet方法的第二个参数是ErrorHandling,用于指定处理异常错误,其内置了以下三种模式:

  • ContinueOnError
  • ExitOnError
  • PanicOnError

定义参数类型

  1. package main
  2. import (
  3. "errors"
  4. "flag"
  5. "fmt"
  6. )
  7. type Name string
  8. func (n *Name)String() string{
  9. return fmt.Sprint(*n)
  10. }
  11. func (n *Name) Set(value string) error {
  12. if len(*n) > 0{
  13. return errors.New("value is already set")
  14. }
  15. *n = Name("joker:"+value)
  16. return nil
  17. }
  18. func main(){
  19. var name Name
  20. flag.Var(&name,"name","帮助信息")
  21. flag.Parse()
  22. fmt.Printf("name: %s",name)
  23. }

我们只需要实现Value的两个接口,如下:

  1. type Value interface {
  2. String() string
  3. Set(string) error
  4. }

然后就实现了自定义参数类型了。

完整示例

定义

  1. func main() {
  2. //定义命令行参数方式1
  3. var name string
  4. var age int
  5. var married bool
  6. var delay time.Duration
  7. flag.StringVar(&name, "name", "张三", "姓名")
  8. flag.IntVar(&age, "age", 18, "年龄")
  9. flag.BoolVar(&married, "married", false, "婚否")
  10. flag.DurationVar(&delay, "d", 0, "延迟的时间间隔")
  11. //解析命令行参数
  12. flag.Parse()
  13. fmt.Println(name, age, married, delay)
  14. //返回命令行参数后的其他参数
  15. fmt.Println(flag.Args())
  16. //返回命令行参数后的其他参数个数
  17. fmt.Println(flag.NArg())
  18. //返回使用的命令行参数个数
  19. fmt.Println(flag.NFlag())
  20. }

使用

命令行参数使用提示:

  1. $ ./flag_demo -help
  2. Usage of ./flag_demo:
  3. -age int
  4. 年龄 (default 18)
  5. -d duration
  6. 时间间隔
  7. -married
  8. 婚否
  9. -name string
  10. 姓名 (default "张三")

正常使用命令行flag参数:

  1. $ ./flag_demo -name 沙河娜扎 --age 28 -married=false -d=1h30m
  2. 沙河娜扎 28 false 1h30m0s
  3. []
  4. 0
  5. 4

使用非flag命令行参数:

  1. $ ./flag_demo a b c
  2. 张三 18 false 0s
  3. [a b c]
  4. 3
  5. 0