Flag
Overview
flag包实现了命令行的解析使用说明(Usage)
定义flags使用flag.Bool(),String(),Int()等 这个声明一个整型flag,-flagname存储在类型为*int的整型指针ip中import "flag"
var ip = flag.Int("flagname", 1234, "help message for flagname")
可以将值绑定到变量中,使用Var()函数
import "flag"
var flagint int
func init() {
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}
或者可以创建满足值接口(接受者为指针)的自定义flag,并可以通过flag词法分析联合
flag.Var(&flagVar, "name", "help message for flagname")
对于这种flags,默认值是变量的初始值,在定义完所有flags,调用
flag.Parse()
解析命令行参数到定义的flags
在解析完flags后,参数在flag.Args()返回的切片中可用或使用个体flag.Arg(i),参数索引从0到flag.NArg()-1
命令行flag语法
允许的格式如下:-flag
-flag=x
-flag x // 只有non-boolean flag允许
可以使用一个或两个负号,它们是等价的,最后一种形式对于boolean flag是不被允许的,因为下列命令行的意义:
cmd -x*
*是Unix Shell的通配符,如果这是个0,false等命名的文件,则会造成歧义,所有,必须使用-flag=false来关闭boolean flag Falg停止解析直到出现non-flag参数(“-“是一种non-flag参数)或在”–“终结 Integer flag接受1234,0664,0x1234和负数,Boolean flag接受如下:
1,0,t,f,true,false,TRUE,FALSE,True,False
Duration flag接受对于time.ParseDuration合理的输入 默认的命令行的flag集合是由高层函数控制,FlagSet类型允许定义独立的flag集合,比如实现命令行接口的子命令,FlagSet方法和默认命令行flag集合的高层函数是类似的
变量(Variables)
CommandLine是默认命令行flags集合,由os.Args解析,顶层的函数比如:BoolVar,Arg等都是CommandLine方法的封装var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
ErrHelp是-h或-help flag触发,但是没有定义这种flag返回的错误
var ErrHelp = errors.New("flag: help requestd")
Usage打印一个关于所用flag用法的用法消息到命令行输出,默认是os.Stderr,当解析flag发生错误时会被调用,该函数是一个变量可以指向自定义函数,默认是打印简单的头部和调用PrintDefaults 关于输出格式的细节和如何控制它,查看PrintDefaults的文档,自定义的usage函数可能选择退出程序,默认情况下,退出无论如何都会发生,因为命令行错误处理策略是ExitOnError
var Usage = func() {
fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
PrintDefaults()
}
函数(Functions)
func Arg(i int) string
Arg返回第i个命令行参数,Arg(0)在flags处理后返回第一个剩下的参数,Arg返回空字符串,如果要求的元素不存在func Args() []string
Args返回non-flag命令行参数func Bool(name string, value bool, usage string) *bool
Bool定义一个指定名称的boolean flag,默认值和usage,返回值是储存flag value的地址func BoolVar(p *bool, name string, value bool, usage string)
BoolVar定义一个指定名称的boolean flag,默认值和usage,flag value存储在传递的p中func Duration(name string, value time.Duration, usage string) *time.Duration
Duration定义一个指定名称的duration flag,默认值和usage,返回值是储存flag value的地址 flag接受time.ParseDuration可接受的值func DurationVar(p *time.Duration, name string, value time.Duration, usage string)
DurationVar定义一个指定名称的duration flag,默认值和usage,flag value存储在p中func Float64(name string, value float64, usage string) *float64
Float64定义一个指定名称的float64 flag,默认值和usage,返回存储flag value的地址func Float64Var(p *float64, name string, value float64, usage string)
Float64Var定义一个指定名称的float64 flag,默认值和usage,flag value存储在p中func Int(name string, value int, usage string) *int
Int定义一个指定名称的int flag,默认值和usage,返回存储flag value的地址func Int64(name string, value int64, usage string) *int64
Int64定义一个指定名称的int64 flag,默认值和usage,返回存储flag value的地址func IntVar(p *int, name string, value int, usage string)
IntVar定义一个指定名称的int flag,默认值和usage,flag value存储在p中func Int64Var(p *int64, name string, value int64, usage string)
Int64Var定义一个指定名称的int64 flag,默认值和usage,flag value存储在p中func NArg() int
NArg返回flag处理后剩下的参数数量func NFlag() int
NFlag返回command-line设置的flag数量func Parse()
Parse解析命令行从os.Args[1:],必须在所有flags定义之后,flags能够被访问之前调用func Parsed() bool
调查是否Parse过func PrintDefaults()
PrintDefaults打印到标准错误输出一个默认设置由定义的command-line flag展示usage message,除非另行配置,对于一个整型flag x,默认有以下形式:-x int
usage-message-for-x (default 7)
描述信息将会出现在分割的行除了一个字节名称的bool flag,对于bool flags,这种类型将会被忽略且如果名称是一个字节,usage message出现在同一行,括号默认被忽略如果默认是该类型的零值,被列出的类型,这int能够被改变通过放置反引号名称在flags的usage string中,第一个这种项目在message中被带到参数名展示在消息中且反引号在展示时会被去掉 比如,给出:
flag.String("l", "", "search `directory` for include files")
输出将会是:
-l directory
search directory for include files
为了改变flag messages的目的地,调用CommandLine.SetOutput
func Set(name string, value string) error
设置command-lien flag值func String(name string, value string, usage string) *string
String定义一个指定名字的string flag,默认值和usage,返回flag value的地址func StringVar(p *string, name string, value string, usage string)
StringVar定义一个指定名字的string flag,默认值和usage,flag value存储在p中func Uint(name string, value uint, usage string) *uint
Uint定义一个指定名字的uint flag,默认值和usage,返回flag value的地址func Uint64(name string, value uint64, usage string) *uint64
Uint64定义一个指定名字的uint64 flag,默认值和usage,返回flag value的地址func Uint64Var(p *uint64, name string, value string, usage string)
Uint64Var定义一个指定名字的uint64 flag,默认值和usage,flag value存储func UintVar(p *uint, name string, value uint, usage string)
UintVar定义一个指定名字的uint flag,默认值和usage,flag value存储在p中func UnquoteUsage(flag *Flag) (name string, usage string)
UnquoteUsage提取反引号名称从flag的usage string并且返回未反引的usage.给出"a `name` to show"返回("name", "a name to show"),如果不存在反引号,名称是对flag value类型的有根据猜测或者是空字符串,如果flag是booleanfunc Var(value Value, name string, usage string)
Var定义一个指定名字的flag和usage string,类型通过第一个参数呈现,value类型,典型是用户定义Value的实现,比如,调用者能够创建一个flag转换逗号分隔的字符串成分割的切片,通过给出Value的slice方法,特别是,Set能分割逗号分隔的字符串到切片中func Visit(fn func(*Flag))
Visit以字典序访问命令行flag,对其调用fn,只访问被设置的flagfunc VisitAll(fn func(*Flag))
VisitAll以字典序遍历所有flag,对其调用fn,包括未被设置的flagErrorHandling定义了如果FlagSet.Parse出错的行为
type ErrorHandling int
如果FlagSet解析失败,这些常量将会描述其行为
const (
ContinueOnError ErrorHandling = itoa // 返回描述性错误
ExitOnError // 调用os.Exit(2)
PanicError // 通过描述性错误调用panic
)
type Flag
Flag用于呈现flag的状态
type Flag struct {
Name string //出现在命令行中的名字
Usage string // 帮助信息
Value Value // 设置的值
DefValue string // 为usage message,default value(as text)
}
func Lookup(name string) *Flag
返回命名的命令行flag的Flag结构体,返回空如果不存在type FlagSet
FlagSet呈现一个定义的flags集合,FlagSet的零值是没有名字且有ContinueOnError错误处理type FlagSet struct {
/*
Usage当flag解析错误时调用,默认错误处理是ExitOnError
*/
Usage() func()
// contains filtered or unexported fields
}
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet
NewFlagSet返回一个新的指定名字和错误处理属性的FlagSet,如果name非空,默认将会被打印在usage message和错误消息中func (*FlagSet) ErrorHandling() ErrorHandling
返回FlagSet的ErrorHandlingfunc (*FlagSet) Init(name string, errorhanding ErrorHandling)
设置FlagSet的名称和错误处理func (*FlagSet) Name() string
返回FlagSet的名称func (f *FlagSet) Output() io.Writer
返回usage message和错误信息的目的地,如果Output未被设置或设为ni,返回os.Stderrfunc (f *FlagSet) Parse(arguments []string)
Parse解析不应该包含命令名称的flag定义,必须在FlagSet定义之后,程序访问flags之前调用,如果-help或-h被设置但没被定义,将会返回ErrHelptype Getter
Getter是一个接口允许值的内容能够被取回,它封装了Value接口,而不是成为其一部分,是由于兼容的原因,该包提供的所有Value类型都符合Getter接口type Getter interface {
Value
Get() interface{}
}
type Value
Value是一个接口对于储存在flag的动态值(默认值被呈现为string) 如果Value有IsBoolFlag() bool 方法返回true,则命令行解析器使得-name和-name=true等价,而不是下一个命令行参数 Set被调用一次,命令行参数顺序对于每个存在的flag,flag包可能调用String()使用nil pointer接收者type Value interface {
String() string
Set(string) error
}
Example
// var.go
// example run by: go run var.go -species=hello -g=smart -deltaT=10s,15s
package main
import (
"flag"
"fmt"
"time"
"errors"
"strings"
)
// a single flag with name "species", default value: "gopher" and usage message
var species = flag.String("species", "gopher", "the species we are studying")
// a variable shared with two flag to support multi name flag
var gopherType string
// use-defined type used to flag value
type interval []time.Duration
func (i *interval) String() string {
return fmt.Sprint(*i)
}
func (i *interval) Set(value string) error {
if len(*i) > 0 {
return errors.New("interval flag already set")
}
for _, dt := range strings.Split(value, ",") {
duration, err := time.ParseDuration(dt)
if err != nil {
return err
}
*i = append(*i, duration)
}
return nil
}
var intervalFlag interval
func init() {
flag.Var(&intervalFlag, "deltaT", "comma-spreaded list of intervals to use between events")
}
func init() {
const (
defaultGopher = "pocket"
usage = "the variety of gopher"
)
flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage)
flag.StringVar(&gopherType, "g", defaultGopher, usage)
}
func main() {
flag.Parse()
fmt.Println(*species)
fmt.Println(gopherType)
fmt.Println(intervalFlag.String())
}