Golang flag包使用詳解(一)


概述

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

命令行語法

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

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

以上語法對於一個或兩個‘-’號,效果是一樣的,但是要注意對於第三種情況,只支持非bool類型,原因是碰到如下情況時

cmd -x * 

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

命令行參數解析方法

使用flag主要包括以下幾步

  1. 定義flag參數,有三種方式

    • 通過flag.String(), Bool(), Int() 等flag.Xxx()方法,該種方式返回一個相應的指針

      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,默認值為該變量類型的初始值

  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]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM