golang學習筆記 --flag

概述

flag包提供了一系列解析命令行參數的功能接口git

命令行語法

命令行語法主要有如下幾種形式github

-flag //只支持bool類型 -flag=x -flag x //只支持非bool類型 

以上語法對於一個或兩個‘-’號,效果是同樣的,可是要注意對於第三種狀況,只支持非bool類型,緣由是碰到以下狀況時ruby

cmd -x * 

*爲0,false有可能表示一個文件名或文件,也有可能表示x標籤的值爲0或false,會產生二義性,所以規定第三種只支持非bool類型。對於整形flag,合法的值能夠爲12340664,0x1234或負數等。對於布爾型flag,能夠爲10tfTF,truefalseTRUEFALSETrueFalseapp

命令行參數解析方法

使用flag主要包括如下幾步函數

  1. 定義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

  2. 調用flag.Parse()解析命令行參數到定義的flag

    flag.Parse()

    解析函數將會在碰到第一個非flag命令行參數時中止,非flag命令行參數是指不知足命令行語法的參數,如命令行參數爲cmd --flag=true abc則第一個非flag命令行參數爲「abc」

  3. 調用Parse解析後,就能夠直接使用flag自己(指針類型)或者綁定的變量了(值類型)

    fmt.Println("ip has value ", *ip) fmt.Println("flagvar has value ", flagvar) 

    還可經過flag.Args()flag.Arg(i)來獲取非flag命令行參數

  4. 若是須要每一個函數的詳細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]
相關文章
相關標籤/搜索