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使ってる。