是一个错误:flag.Parse() 无法在 bool arg 之后获取值吗?

you*_*gzy -2 go

为什么无法获取命令行中 bool 类型 arg 后面的值?
这是我的测试代码:

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 Code Online (Sandbox Code Playgroud)

运行它作为:

  • go run flag.go -s test -b true -i 10
    得到:stringVal: test , boolValue: true , intVal: -1
  • go run flag.go -s test -b false -i 10
    得到:stringVal: test , boolValue: true , intVal: -1
  • go run flag.go -b false -s test -i 10
    得到:stringVal: , boolValue: true , intVal: -1
  • go run flag.go -s test -i 10 -b false
    得到:stringVal: test , boolValue: true , intVal: 10

去版本:1.16

mea*_*gar 6

布尔标志是根据标志的存在或不存在来设置的。它们通常默认为 false,并且该标志的存在用于修改默认行为。

例如...

  • 要显示目录的ls列表,您使用ls -l, 而不是ls -l true
  • rm为了通过交互式提示删除来使其更安全,您使用rm -i,而不是rm -i true
  • 要显示人类可读的输出df,您使用df -h, notdf -h true

您放置在 后面的true和是作为参数而不是标志提供给程序的,它们的存在会中断标志的进一步处理。false-b

将以下内容添加到函数末尾main

fmt.Println("Remaining args", flag.Args())
Run Code Online (Sandbox Code Playgroud)

给定一个诸如 的调用go run flag.go -b false -s test -i 10,您将看到标志处理在 处停止false,并且其余参数作为非标志参数传递给您的程序:

$ go run flag.go -b false -s test -i 10
stringVal:  , boolValue: true , intVal: -1
Remaining args [false -s test -i 10]
Run Code Online (Sandbox Code Playgroud)

顺便说一句,“布尔”标志背后的一般原理是,您为程序提供一些默认行为,并提供两个标志:一个修改默认值,另一个相反的标志否定修改,恢复默认值。处理标志时,最后一个标志获胜。

例如,rm提供-i使命令交互,以及-f否定-i标志。

alias rm="rm -i"这允许您在 shell 中进行设置,这意味着为了安全起见,所有调用rm都会-i应用该标志,在删除文件之前提示您。但是,如果您想运行非交互式rm,您仍然可以键入rm -f,它会扩展为rm -i -f,最后一个标志 ( -f) 获胜。rm否则,每次需要非交互式调用时,您都必须销毁别名、运行并恢复别名。