flag包提供了一系列解析命令行參數的功能接口git
命令行語法主要有如下幾種形式github
-flag //只支持bool類型 -flag=x -flag x //只支持非bool類型
以上語法對於一個或兩個‘-’號,效果是同樣的,可是要注意對於第三種狀況,只支持非bool類型,緣由是碰到以下狀況時ruby
cmd -x *
*爲0,false有可能表示一個文件名或文件,也有可能表示x標籤的值爲0或false,會產生二義性,所以規定第三種只支持非bool類型。對於整形flag,合法的值能夠爲1234
, 0664
,0x1234
或負數等。對於布爾型flag,能夠爲1
, 0
, t
, f
, T
, F
,true
, false
, TRUE
, FALSE
, True
, False
等app
使用flag主要包括如下幾步函數
定義flag參數,有三種方式ui
經過flag.String(), Bool(), Int()
等flag.Xxx()
方法,該種方式返回一個相應的指針spa
import "flag" var ip = flag.Int("flagname", 1234, "help message for flagname")
經過flag.XxxVar()
方法將flag綁定到一個變量,該種方式返回值類型,如命令行
var flagvar int func init() { flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") }
經過flag.Var()
綁定自定義類型,自定義類型須要實現Value接口(Receives必須爲指針),如指針
flag.Var(&flagVal, "name", "help message for flagname")
對於這種類型的flag,默認值爲該變量類型的初始值code
調用flag.Parse()
解析命令行參數到定義的flag
flag.Parse()
解析函數將會在碰到第一個非flag命令行參數時中止,非flag命令行參數是指不知足命令行語法的參數,如命令行參數爲cmd --flag=true abc
則第一個非flag命令行參數爲「abc」
調用Parse解析後,就能夠直接使用flag自己(指針類型)或者綁定的變量了(值類型)
fmt.Println("ip has value ", *ip) fmt.Println("flagvar has value ", flagvar)
還可經過flag.Args()
, flag.Arg(i)
來獲取非flag命令行參數
若是須要每一個函數的詳細demo,可參見Gopkg:flag
示例1: 獲取「species」 flag的值,默認爲「gopher」
var species = flag.String("species", "gopher", "the species we are studying")
示例2: 兩個flag共享同一個變量,通常用於同時實現完整flag參數和對應簡化版flag參數,須要注意初始化順序和默認值
var gopherType string func init() { const ( defaultGopher = "pocket" usage = "the variety of gopher" ) flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage) flag.StringVar(&gopherType, "g", defaultGopher, usage+"(shorthand)") }
示例3: 將flag綁定用戶自定義類型。按咱們先前所說,只須要實現Value接口,但實際上,若是須要取值的話,須要實現Getter接口,看下接口定義就明白了:
type Getter interface { Value Get(string) interface{} } type Value interface { String() string Set(string) error }
接下來,咱們實現一個解析並格式化命令行輸入的時間集合的例子,以下
package main import ( "errors" "flag" "fmt" "strings" "time" ) type interval []time.Duration //實現String接口 func (i *interval) String() string { return fmt.Sprintf("%v", *i) } //實現Set接口,Set接口決定了如何解析flag的值 func (i *interval) Set(value string) error { //此處決定命令行是否能夠設置屢次-deltaT 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-separated list of intervals to use between events") } func main() { flag.Parse() fmt.Println(intervalFlag) }
運行結果:
//./commandLine -deltaT 61m,72h,80s [1h1m0s 72h0m0s 1m20s]