如何使用Go的标志包打印位置参数的用法?

faz*_*azy 6 go

鉴于这个简单的Go程序,它只需要一个命令行参数,我该如何改进它以便flag.Usage()提供有用的输出?

package main

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

func main() {
    flag.Parse()
    if len(flag.Args()) == 0 { 
        flag.Usage()
        os.Exit(1)
    }

    args := flag.Args()
    fmt.Println(args[0])
}
Run Code Online (Sandbox Code Playgroud)

当前输出没有给出参数:

$ ./args
Usage of ./args:
Run Code Online (Sandbox Code Playgroud)

(即用法是空的,因为我无法告诉usage()函数需要哪些参数).

我可以删除flag.Usage()并替换为这样的东西:

fmt.Fprintln(os.Stderr, "Usage:", os.Args[0], "<argument>")
Run Code Online (Sandbox Code Playgroud)

但是,如果有一个很好的方法,我不想重新发明轮子flag.Usage().特别是因为它已经处理了可选参数:

$ ./args -foo
flag provided but not defined: -foo
Usage of ./args:
Run Code Online (Sandbox Code Playgroud)

dwa*_*ter 12

flag.Usage()只会为您提供有关已定义标志的有用信息.因此,您要么将参数定义为标记via var foo = flag.Int(...).

另一种选择是定义自己的使用处理程序.请参阅下面的一个简单示例,该示例将打印自定义消息以及所有已定义标志的默认值.这样您Usage将自定义打印以防万一flag.Parse()失败.

package main
import (
    "flag"
    "fmt"
    "os"
)

func myUsage() {
     fmt.Printf("Usage: %s [OPTIONS] argument ...\n", os.Args[0])
     flag.PrintDefaults()
}

func main() {
     flag.Usage = myUsage
     /* ... */
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这很有效.我不确定为什么Go不能定义位置参数,因为我认为这些也很常见.如果我可以定义一个没有名称的参数,那么我就不需要创建一个自定义的`Usage()`函数,内置函数可以与其他函数一起处理它.如果没有太多额外代码,您的解决方 :) (6认同)