flagパッケージ使用メモ

More than 3 years have passed since last update.

Go言語でコマンドラインオプションを使うならflagを使ったらいいと聞いて。

os.Argsでも取れますが、flagの方が楽で便利です。


NArg()はParse()しないと取れない

試しに引数の数でも取ってみようかと思い、下記コードを実行したが、引数の数が取れず・・・

package main

import (
"flag"
"fmt"
)

func main() {
fmt.Println("flag.NArg():", flag.NArg())
}

$ go run main.go a b c

flag.NArg(): 0

なんでなのかな〜と思ってリファレンスを見てみる


NArg is the number of arguments remaining after flags have been processed.


まぁよくわからないので、Google翻訳にかけてみる。


第nargフラグが処理された後、残りの引数の数である。


処理された後ってあるからなんかしないとダメなのか?

Parse()くらいしか処理するって感じの関数見当たらないし、これでいいか。

package main

import (
"flag"
"fmt"
)

func main() {
flag.Parse()
fmt.Println("flag.NArg():", flag.NArg())
}

$ go run main.go a b c

flag.NArg(): 3

行けました。

どうやらParse()が必要だったようです。

ちなみに、フラグ状態の引数を渡すと「定義されていない」とエラーが出ます。

$ go run main.go -a -b -c

flag provided but not defined: -a


フラグ作った時の戻り値をそのまま使えない

フラグ作るのはflag.Int()等、型ごとに関数があるのでそれを使うが、そのまま使おうとしてもポインタの値が出てくる。

package main

import (
"flag"
"fmt"
)

func main() {
var i = flag.Int("i", 0, "usage")

flag.Parse()

fmt.Println(i)
}

$ go run main.go

0x2081a2230

↑本当は0と出てきて欲しい。

フラグを作った時の戻り値がポインタなので、実体参照してやる。

package main

import (
"flag"
"fmt"
)

func main() {
var i = flag.Int("i", 0, "usage")

flag.Parse()

fmt.Println(*i)
}

$ go run main.go

0
$ go run main.go -i=7
7

デフォルト値の0も出てきたし、値指定した時の7も出てきた。


余談:flagの中身も結局os.Args使ってる。

https://golang.org/src/flag/flag.go?s=27448:27501#L840