2

如果提供的输入是以下形式,Golang 的标志包会正确读取命令行标志和参数:go run main.go -o filename.txt arg1 arg2

但是,如果我尝试提供像 : 这样的输入go run main.go arg1 arg2 -o filename.txt,那么 main.go 之后的所有内容都会被读取为参数。

如何使这种风格发挥作用?

我的程序:

package main

import (
    "flag"
    "fmt"
)

func main() {

    var output string
    flag.StringVar(&output, "o", "", "Writes output to the file specified")
    flag.Parse()
    fmt.Println("Positional Args : ", flag.Args())
    fmt.Println("Flag -o : ", output)
}

go run main.go -o filename.txt arg1 arg2

输出:

Positional Args :  [arg1 arg2]
Flag -o :  filename.txt

go run main.go arg1 arg2 -o filename.txt

输出:

Positional Args :  [arg1 arg2 -o filename.txt]
Flag -o :
4

1 回答 1

0

如果你用 os.Args 的内容来回摆动,可以接受arg1 arg2 -o filename.txt

遍历从 for 循环中的命令行传入的 os.Args

如果看到 - 则设置一个条件,指示已看到第一个标志

如果设置了条件,则填充“notargs”列表。否则,填充“args”列表

这里有一些额外的复杂性,因为用于将 os.Args 设置为将执行标志处理的值的 args 列表必须包含程序名称(原始 os.Arg[0])作为第一个值

此解决方案不适用于-o filename.txt arg1 arg2

package main

import (
    "flag"
    "fmt"
    "os"
)

func main() {

    var output string
    var args[]string
    var notargs[]string
    var in_flags bool=false
    for i:=0; i<len(os.Args); i++ {
      if os.Args[i][0]=='-' {
       in_flags=true
      }
      if i==0 || in_flags {
        notargs=append(notargs,os.Args[i])
      } else {
        args=append(args,os.Args[i])
      }
    }
    os.Args=notargs
    flag.StringVar(&output, "o", "", "Writes output to the file specified")
    flag.Parse()
    fmt.Println("args ",args)
    fmt.Println("Flag -o : ", output)
}
于 2021-11-27T16:05:29.913 回答