Golang标志库:无法覆盖打印出命令行用法的Usage函数

Str*_*s3D 2 flags command-line-tool go

我正在使用一个简单的命令行工具,我发现默认的Usage消息有点缺乏.我想定义自己的,我认为我正在做正确的我指的是这个例子.

我注释掉了我编写的大部分代码,因此包含main函数的文件现在看起来像这样:

package main

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

func main() {
    // set the custom Usage function
    setupFlags(flag.CommandLine)
    // define flags...
    // then parse flags
    flag.Parse()
    // custom code that uses flag values...
}

func setupFlags(f *flag.FlagSet) {
    f.Usage = func() {
        fmt.Println("foo bar")
    }
}
Run Code Online (Sandbox Code Playgroud)

看起来这应该有效,但事实并非如此.运行时,<binary> -h我得到默认用法消息,而不是我foo bar在自定义函数中定义的自定义消息.我在OSX上使用Go 1.3.3版.我发现了这个提交,但它适用于Go 1.4rc2.

我究竟做错了什么?

icz*_*cza 7

编辑:

实际上重新审视你的代码它的工作原理!您使用的是什么版本的Go?也许你需要重建你的代码.

Usage要调用哪个函数的决定是在flag.go源文件,第708行,未导出的函数中usage()(这是来自Go 1.4):

func (f *FlagSet) usage() {
    if f.Usage == nil {
        if f == CommandLine {
            Usage()
        } else {
            defaultUsage(f)
        }
    } else {
        f.Usage()
    }
}
Run Code Online (Sandbox Code Playgroud)

这告诉它FlagSet.Usage是否不会nil,它将被调用.如果没有为您调用,则很可能您使用的是1.4之前的Go版本(您在评论中确认).

但是,由于您使用的是默认的flag.CommandLineflagset,您可以简单地写:

// Note "flag.Usage" instead of "f.Usage"

flag.Usage = func() {
    fmt.Println("foo bar")
}
Run Code Online (Sandbox Code Playgroud)