背景#
flag.Bool
およびflag.BoolVar
には奇妙な問題が発生します。
デフォルト値を true
に設定すると、
// flag.BoolVar
func main() {
var getBool bool
flag.BoolVar(&getBool, "get", true, "booleanを取得")
flag.Parse()
fmt.Println(getBool)
}
# 結果
go run main.go -get false
true
// flag.Bool
func main() {
var getBool *bool
getBool = flag.Bool("get", true, "booleanを取得")
flag.Parse()
fmt.Println(*getBool)
}
# 結果
go run main.go -get false
true
しかし、デフォルト値を false
に設定し、コマンドライン引数を true
にすると、コードの結果は正常になります(結果が一致するため、一方のみを表示します)。
func main() {
var getBool *bool
getBool = flag.Bool("get", false, "booleanを取得")
flag.Parse()
fmt.Println(*getBool)
}
# 結果
go run main.go -get true
true
なぜ#
では、コードのコメントを見てみましょう。
// src/flag/flag.go
// Flagはフラグの状態を表します。
type Flag struct {
Name string // コマンドラインに表示される名前
Usage string // ヘルプメッセージ
Value Value // 設定された値
DefValue string // デフォルト値(テキストとして);使用メッセージ用
}
// Valueはフラグに格納された動的値へのインターフェースです。
// (デフォルト値は文字列として表されます。)
//
// ValueがIsBoolFlag() boolメソッドを持ち、trueを返す場合、
// コマンドラインパーサーは-nameを-name=trueと等価にします
// 次のコマンドライン引数を使用するのではなく。
//
// Setは、各フラグが存在するコマンドライン順序で一度呼び出されます。
// flagパッケージは、ゼロ値のレシーバーを持つ[String]メソッドを呼び出すことがあります。
// たとえば、nilポインタなど。
type Value interface {
String() string
Set(string) error
}
bool フラグ -name
はパーサーによって - name=true として解析され、次の引数は解析されません。
# 以下のように -b の後の false は解析されません
# 以下のコマンドは go run main.go -b=true と同等です
go run main.go -b false
どう解決するか#
-name=false
を -name false
の代わりに使用します。
# 結果
go run main.go -get=true -come=false -num 1
true
false
1