2種類のやり方があります
tl; dr
- flag を使うのが良さそう
- 型指定やオプショナル引数、デフォルト値の設定等、色々できるから
flag
使い方
main.go
package main
import (
"flag"
"fmt"
)
func main() {
flag.Parse()
fmt.Println(flag.Args())
}
$ go run main.go foo bar baz
[foo bar baz]
- 解析には flag.Parse() を呼び出します
- flag.Parse の内部では os.Args[1:] が渡されて解析される
- os.Args[0:] には実行コマンドが格納されている
- flag.Parse の内部では os.Args[1:] が渡されて解析される
- Parse は全ての flag が定義された後かつ、いづれかの flag にアクセスする前にコールする必要がある
- これを守らないと
flag provided but not defined: -hogehoge
みたいなエラーが出る
- これを守らないと
//github.com/golang/go/blob/master/src/flag/flag.go#L963-L966
// Parse parses flag definitions from the argument list, which should not
// include the command name. Must be called after all flags in the FlagSet
// are defined and before flags are accessed by the program.
// The return value will be ErrHelp if -help or -h were set but not defined.
オプショナルな引数を使う
こんな感じ
package main
import (
"fmt"
"flag"
"os"
)
func main(){
f := flag.String("flag1", "hoge", "flag 1")
flag.Parse()
fmt.Println("Hello %s", *f)
}
$ go run sample.go -flag1=fuga
Hello fuga
$ go run sample.go
Hello hoge
- オプションを定義するには以下の二つの方法がある
- var str = flag.String("オプション名", "初期値", "説明")
- flag.StringVar(&str, "オプション名", "初期値", "説明")
- string や int 以外にもいろんな型がサポートされている(詳しくはhttps://golang.org/pkg/flag/)
- 戻り値がポインタなので、使うときは実体参照する
- オプションの指定方法
- -flag
- -flag=x
- -flag x // non-boolean flags only
- (※ハイフンは二つでも認識されるらしい)
os.Args
この辺を読む
go test で flag を使う
- 普通に
go test
コマンドにフラグを渡してやれば良い - Go1.13からテスト実行時のフラグの処理順序が変更されたっぽく、init 関数でフラグの定義をしている場合、parse する前に
testing.Init()
しないとテストが落ちるようになったらしいので注意
https://budougumi0617.github.io/2019/10/30/go-testing2019/#testing-init-%E9%96%A2%E6%95%B0%E3%81%8C%E8%BF%BD%E5%8A%A0%E3%81%95%E3%82%8C%E3%81%9F
VSCode の拡張で使いたい
- 以下のような設定を setting.json に記述する
- VSCode のエディタ上のテスト関数の上に表示される
run test
ボタンでテスト実行した際に、自動でフラグが付加される
"go.testFlags": [
"-flag1=hoge",
"-flag2=fuga"
]