导入flag包
import flag
flag参数类型
flag包支持的命令行参数类型有bool、int、int64、uint、uint64、float float64、string、duration。
| 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.Type()
基本格式如下:flag.Type(flag名, 默认值, 帮助信息)*Type 例如我们要定义姓名、年龄、婚否三个命令行参数,我们可以按如下方式定义:
name := flag.String("name", "张三", "姓名")age := flag.Int("age", 18, "年龄")married := flag.Bool("married", false, "婚否")delay := flag.Duration("d", 0, "时间间隔")
需要注意的是,此时name、age、married、delay均为对应类型的指针。
flag.TypeVar()
基本格式如下: flag.TypeVar(Type指针, flag名, 默认值, 帮助信息) 例如我们要定义姓名、年龄、婚否三个命令行参数,我们可以按如下方式定义:
var name stringvar age intvar married boolvar delay time.Durationflag.StringVar(&name, "name", "张三", "姓名")flag.IntVar(&age, "age", 18, "年龄")flag.BoolVar(&married, "married", false, "婚否")flag.DurationVar(&delay, "d", 0, "时间间隔")
flag.Parse()
通过以上两种方法定义好命令行flag参数后,需要通过调用flag.Parse()来对命令行参数进行解析。
支持的命令行参数格式有以下几种:
-flag xxx(使用空格,一个-符号)--flag xxx(使用空格,两个-符号)-flag=xxx(使用等号,一个-符号)--flag=xxx(使用等号,两个-符号)
其中,布尔类型的参数必须使用等号的方式指定。
Flag解析在第一个非flag参数(单个”-“不是flag参数)之前停止,或者在终止符”–“之后停止。
flag其他函数
flag.Args() ////返回命令行参数后的其他参数,以[]string类型flag.NArg() //返回命令行参数后的其他参数个数flag.NFlag() //返回使用的命令行参数个数
子命令的使用
package mainimport ("flag""fmt")func main(){var name stringflag.Parse()goCmd := flag.NewFlagSet("go",flag.ExitOnError)goCmd.StringVar(&name,"name","Go语言","帮助信息")phpCmd := flag.NewFlagSet("php",flag.ExitOnError)phpCmd.StringVar(&name,"n","php语言","帮助信息")args := flag.Args()if len(args) <= 0{return}switch args[0] {case "go":_ = goCmd.Parse(args[1:])fmt.Println("go......")case "php":_ = phpCmd.Parse(args[1:])fmt.Println("php......")}fmt.Println(name)}
由于需要处理子命令,因此调用了flag.NewFlagSet方法。该方法会返回带有指定名称和错误处理属性的空命令集,相当于创建一个新的命令集去支持子命令。需要注意的是,flag.NewFlagSet方法的第二个参数是ErrorHandling,用于指定处理异常错误,其内置了以下三种模式:
- ContinueOnError
- ExitOnError
- PanicOnError
定义参数类型
package mainimport ("errors""flag""fmt")type Name stringfunc (n *Name)String() string{return fmt.Sprint(*n)}func (n *Name) Set(value string) error {if len(*n) > 0{return errors.New("value is already set")}*n = Name("joker:"+value)return nil}func main(){var name Nameflag.Var(&name,"name","帮助信息")flag.Parse()fmt.Printf("name: %s",name)}
我们只需要实现Value的两个接口,如下:
type Value interface {String() stringSet(string) error}
然后就实现了自定义参数类型了。
完整示例
定义
func main() {//定义命令行参数方式1var name stringvar age intvar married boolvar delay time.Durationflag.StringVar(&name, "name", "张三", "姓名")flag.IntVar(&age, "age", 18, "年龄")flag.BoolVar(&married, "married", false, "婚否")flag.DurationVar(&delay, "d", 0, "延迟的时间间隔")//解析命令行参数flag.Parse()fmt.Println(name, age, married, delay)//返回命令行参数后的其他参数fmt.Println(flag.Args())//返回命令行参数后的其他参数个数fmt.Println(flag.NArg())//返回使用的命令行参数个数fmt.Println(flag.NFlag())}
使用
命令行参数使用提示:
$ ./flag_demo -helpUsage of ./flag_demo:-age int年龄 (default 18)-d duration时间间隔-married婚否-name string姓名 (default "张三")
正常使用命令行flag参数:
$ ./flag_demo -name 沙河娜扎 --age 28 -married=false -d=1h30m沙河娜扎 28 false 1h30m0s[]04
使用非flag命令行参数:
$ ./flag_demo a b c张三 18 false 0s[a b c]30
