Why could not get the values that following bool type arg in the command line?
Here's my test code:
import (
"flag"
"fmt"
)
var stringVal string
var intVal int
var boolValue bool
func init() {
flag.StringVar(&stringVal, "s", "", "string value")
flag.BoolVar(&boolValue, "b", false, "bool value")
flag.IntVar(&intVal, "i", -1, "int value")
}
func main() {
flag.Parse()
fmt.Println("stringVal:", stringVal, ", boolValue:", boolValue, ", intVal:", intVal)
}
Run it as:
go run flag.go -s test -b true -i 10
Got: stringVal: test , boolValue: true , intVal: -1go run flag.go -s test -b false -i 10
Got: stringVal: test , boolValue: true , intVal: -1go run flag.go -b false -s test -i 10
Got: stringVal: , boolValue: true , intVal: -1go run flag.go -s test -i 10 -b false
Got: stringVal: test , boolValue: true , intVal: 10
Go version: 1.16
CodePudding user response:
Boolean flags are set based on the presence or absence of the flag. They typically default to false, and the presence of the flag is used to modify the default behavior.
For example...
- to display the long listing of a directory with
ls
, you usels -l
, notls -l true
- to make
rm
safer by having it interactively prompt for deletes, you userm -i
, notrm -i true
- to display human-readable output with
df
, you usedf -h
, notdf -h true
The true
and false
you're placing after the -b
are being provided to your program as arguments, not as flags, and their presence interrupts further processing of flags.
Add the following to the end of your main
function:
fmt.Println("Remaining args", flag.Args())
Given an invocation such as go run flag.go -b false -s test -i 10
, you'll see that flag processing stopped at false
, and that the remaining arguments are passed to your program as non-flag arguments:
$ go run flag.go -b false -s test -i 10
stringVal: , boolValue: true , intVal: -1
Remaining args [false -s test -i 10]
As an aside, the general philosophy behind "boolean" flags is that you give your program some default behavior, and provide two flags: One which modifies that default, and an opposite flag that negates the modification, restoring the default. When processing flags, the last flag will win.
For example, rm
provides -i
to make the command interactive, and -f
to negate the -i
flag.
This allows you to set alias rm="rm -i"
in your shell, meaning all invocations of rm
will have the -i
flag applied for safety, prompting you before removing files. However, if you want to run a non-interactive rm
, you can still type rm -f
, which expands to be rm -i -f
, and the last flag (-f
) wins. Otherwise, you'd have destroy the alias, run rm
and then restore the alias every time you wanted a non-interactive invocation.
CodePudding user response:
A boolean flag tests the existence of the flag, not the value of it. If you want to set a value, use:
go run flag.go -s test -b=false -i 10