Go解析コマンドラインパラメータ(フラグパッケージ)

3344 ワード

コマンドラインプログラム(ツール、server)を書く場合は、コマンドラインパラメータを解析するのが一般的です。様々な言語は、開発者が使いやすいように、それぞれの方法やライブラリを提供します。go標準ライブラリでは、コマンドライン解析が容易なパッケージを提供しています。つまり、Goのフラグパケットはコマンドラインのパラメータを解析するために使用されます。 
一、命令行フラグ文法形式
コマンドラインフラッグの文法は以下の3つのタイプがあります。
-flag //    bool  
-flag=x
-flag x //     bool  
このうち、第1の形態は、bookタイプにしか使用できない。第三の形式はbookタイプでないflagsにしか使えません。このようなコマンドcmd-x*に対して、ファイル名が0やfalseなどあると、コマンドの本来の意味が変わります。bookタイプは-flagsという形をサポートしていますので、go言語はParse()メソッドでbookタイプを特殊処理しました。デフォルトでは-flagsを提供すると、対応する値はtrueです。そうでなければ、flags.Bool/BoolVarで指定されたデフォルト値です。表示地をfalseに設定したい場合は、-flags=falseを使用します。
二、フラグを定義する方式
flagsを定義するには2つの方法があります。
1)flagga.Xxx()のうち、XxxはInt、Stringなどとすることができます。対応する種類のポインタを返します。
var ip = flag.Int("flagname", 123, "int flag for flagname")
2)フラッグ.XxVar()は、フラッグを変数に結び付けます。
var flagvar int
flag.IntVar(&flagvar, "flagname", 123, "int flag for flagname")
また、カスタムフラッグを作成することもできます。フラッグ.Valueインターフェースを実現すれば(receiverがポインタであることを要求します)、この場合は次のように定義されます。
flag.Var(&flagVal, "name", "help message for flagname")
例えば、英語のコンマで区切られた文字列を解析してsliceに直接に行くと、次のように定義されます。
type sliceValue []string

func newSliceValue(vals []string, p *[]string) *sliceValue {
    *p = vals
    return (*sliceValue)(p)
}

func (s *sliceValue) Set(val string) error {
    *s = sliceValue(strings.Split(val, ","))
    return nil
}

func (s *sliceValue) Get() interface{} { return []string(*s) }

func (s *sliceValue) String() string { return strings.Join([]string(*s), ",") }
その後、このように使うことができます。
var languages []string
flag.Var(newSliceValue([]string{}, &languages), "slice", "I like programming `languages`")
こうして-slice「go,php」という形でパラメータを伝えていくと、laguagesが得たのが「go,php」です。フラッグバッグにはDurationという非基本的なタイプのサポートがありますが、このような方法が使われています。
三、主なAPI
私たちがよく使うAPIは以下の通りです。
1.コマンドラインパラメータを直接取得する
//      name    ,    value,   usage
//           
//         Int(),Bool() 。
func String(name string, value string, usage string) *string
2.取得したコマンドラインのパラメータを指定値に割り当てます。

//     p     ,         
//         IntVar(),BoolVar() 。
func StringVar(p *string, name string, value string, usage string)
3.使用方法を示す
// Usage      
var Usage = func() {
    // ...
}
4.解析パラメータ
//     ,            
func Parse()
四、使用例
コードの例:
ackage main

import (
    "flag"
    "fmt"
//    "os"
)

func main() {
//    fmt.Println(os.Args)
    ok := flag.Bool("ok", false, "is ok")
    id := flag.Int("id", 0, "id")
    port := flag.String("port", ":8080", "http listen port")
    var name string
    flag.StringVar(&name, "name", "Jack", "name")

    flag.Parse()
//    flag.Usage()
    others := flag.Args()

    fmt.Println("ok:", *ok)
    fmt.Println("id:", *id)
    fmt.Println("port:", *port)
    fmt.Println("name:", name)
    fmt.Println("other:", others)
}
実行例は以下の通りです。
$ go run flag.go -ok -id 11111 -port 8899 -name TestUser very good
ok: true
id: 11111
port: 8899
name: TestUser
other: [very good]