import "flag"
git
flag包實現了命令行參數的解析。每一個參數認爲一條記錄,根據實際進行定義,到一個set集合。每條都有各自的狀態參數。github
在使用flag時正常流程: golang
1. 經過flag.String(), flag.Bool(), flag.Int()等函數來定義命令行中須要使用的參數。
函數
2. 在定義完flag後,經過調用flag.Parse()來進行對命令行參數的解析。
ui
3. 獲取flag.String(), flag.Bool(), flag.Int()等方法的返回值,即對應用戶輸入的參數.
spa
注意的是flag.Xxx()返回的值是變量的內存地址,要獲取值時要經過在變量前加*(星號)獲取.
命令行
說明:
像flag.Int、flag.Bool、flag.String這樣的函數格式都是同樣的,調用的時候須要傳入3個參數
參數的說明以下:
第一個arg表示參數名稱,在控制檯的時候,提供給用戶使用.
第二個arg表示默認值,若是用戶在控制檯沒有給該參數賦值的話,就會使用該默認值.
第三個arg表示使用說明和描述,在控制檯中輸入-arg的時候會顯示該說明,相似-help
可註冊flag類型有:Bool / Int / Int64 / Uint / Uint64 / Float / Float64 / String / Duration / Var3d
type Flag struct { Name string // flag在命令行中的名字 Usage string // 幫助信息 Value Value // 要設置的值 DefValue string // 默認值(文本格式),用於使用信息 }
Flag類型表明一條flag的狀態。指針
type FlagSet struct { // Usage函數在解析flag出現錯誤時會被調用 // 該字段爲一個函數(而非採用方法),以便修改成自定義的錯誤處理函數 Usage func() // 內含隱藏或非導出字段 }
FlagSet表明一個已註冊的flag的集合。FlagSet零值沒有名字,採用ContinueOnError錯誤處理策略。code
func Int(name string, value int, usage string) *int
Int用指定的名稱、默認值、提示信息註冊一個int類型flag。返回一個保存了該flag的值的指針。
func IntVar(p *int, name string, value int, usage string)
IntVar用指定的名稱、默認值、使用信息註冊一個int類型flag,並將flag的值保存到p指向的變量。
func Parse()
從os.Args[1:]中解析註冊的flag。必須在全部flag都註冊好而未訪問其值時執行。未註冊卻使用flag -help時,會返回ErrHelp。
即:將輸入的flag和註冊的flag進行匹配解析
func Parsed() bool
返回是否Parse已經被調用過。
package main import ( "flag" "fmt" ) func main() { married := flag.Bool("married", false, "Are you married?") age := flag.Int("age", 22, "How old are you?") name := flag.String("name", "", "What your name?") var address string //flag.StringVar這樣的函數第一個參數換成了變量地址,後面的參數和flag.String是同樣的。 flag.StringVar(&address, "address", "GuangZhou", "Where is your address?") flag.Parse() //解析輸入的參數 fmt.Println("輸出的參數married的值是:", *married)//不加*號的話,輸出的是內存地址 fmt.Println("輸出的參數age的值是:", *age) fmt.Println("輸出的參數name的值是:", *name) fmt.Println("輸出的參數address的值是:", address) }
從運行結果中能夠看出,address參數咱們並無指定值,則輸出的就是默認值. 另外,-arg後面的=號也不是必須的,能夠用空格代替. 若是要查看該程序的全部參數的使用,可使用-help來查看,以下:
func PrintDefaults()
PrintDefault會向標準錯誤輸出寫入全部註冊好的flag的默認值。
func NFlag() int
NFlag返回已被設置的flag的數量。
func Lookup(name string) *Flag
返回已經已註冊flag的Flag結構體指針;若是flag不存在的話,返回nil。
func NArg() int
NArg返回解析flag以後剩餘參數的個數。
func Args() []string
返回解析以後剩下的非flag參數。(不包括命令名).就是沒法進行flag匹配的有哪些,
func Arg(i int) string
返回解析以後剩下的第i個參數,從0開始索引。
func Var(value Value, name string, usage string)
Var方法使用指定的名字、使用信息註冊一個flag。該flag的類型和值由第一個參數表示,該參數應實現了Value接口。例如,用戶能夠建立一個flag,能夠用Value接口的Set方法將逗號分隔的字符串轉化爲字符串切片。
func Set(name, value string) error
設置已註冊的flag的值,修改或者設置
func Visit(fn func(*Flag))
按照字典順序遍歷標籤,而且對每一個標籤調用fn。 這個函數只遍歷解析時進行了設置的標籤。[就是執行時提供非默認的值]
func VisitAll(fn func(*Flag))
按照字典順序遍歷標籤,而且對每一個標籤調用fn。 這個函數會遍歷全部標籤,無論解析時有無進行設置。
package main import ( "flag" "fmt" ) func main() { // golang的flag包的一些基本使用方法 // 待使用的變量 var id int var name string var male bool // 是否已經解析 fmt.Println("parsed? = ", flag.Parsed()) // 設置flag參數 (變量指針,參數名,默認值,幫助信息) // 也能夠用如下帶返回值的方法代替,不過他們返回的是指針,比較麻煩點 // Int(name string, value int, usage string) *int // String(name string, value string, usage string) *string // Bool(name string, value bool, usage string) *bool flag.IntVar(&id, "id", 123, "help msg for id") flag.StringVar(&name, "name", "default name", "help msg for name") flag.BoolVar(&male, "male", false, "help msg for male") // 解析 flag.Parse() // 是否已經解析 fmt.Println("parsed? = ", flag.Parsed()) // // 獲取非flag參數 fmt.Println(flag.NArg()) fmt.Println("------ Args start ------") fmt.Println(flag.Args()) for i, v := range flag.Args() { fmt.Printf("arg[%d] = (%s).\n", i, v) } fmt.Println("------ Args end ------") // // visit只包含已經設置了的flag fmt.Println("------ visit flag start ------") flag.Visit(func(f *flag.Flag) { fmt.Println(f.Name, f.Value, f.Usage, f.DefValue) }) fmt.Println("------ visit flag end ------") // // visitAll只包含全部的flag(包括未設置的) fmt.Println("------ visitAll flag start ------") flag.VisitAll(func(f *flag.Flag) { fmt.Println(f.Name, f.Value, f.Usage, f.DefValue) }) fmt.Println("------ visitAll flag end ------") // // flag參數 fmt.Printf("id = %d\n", id) fmt.Printf("name = %s\n", name) fmt.Printf("male = %t\n", male) // flag參數默認值 fmt.Println("------ PrintDefaults start ------") flag.PrintDefaults() fmt.Println("------ PrintDefaults end ------") //非flag參數個數 fmt.Printf("NArg = %d\n", flag.NArg()) // 已設置的flag參數個數 fmt.Printf("NFlag = %d\n", flag.NFlag()) }
# go run demo2_flag.go -id 234 -name "xx" -male=true p1 p2 p3 parsed? = false parsed? = true 3 ------ Args start ------ [p1 p2 p3] arg[0] = (p1). arg[1] = (p2). arg[2] = (p3). ------ Args end ------ ------ visit flag start ------ id 234 help msg for id 123 male true help msg for male false name xx help msg for name default name ------ visit flag end ------ ------ visitAll flag start ------ id 234 help msg for id 123 male true help msg for male false name xx help msg for name default name ------ visitAll flag end ------ id = 234 name = xx male = true ------ PrintDefaults start ------ -id int help msg for id (default 123) -male help msg for male -name string help msg for name (default "default name") ------ PrintDefaults end ------ NArg = 3 NFlag = 3
在flag包中,進行了進一步封裝:將FlagSet的方法都從新定義了一遍,也就是提供了一序列函數,而函數中只是簡單的調用已經實例化好了的FlagSet