Go 如何在我的应用程序中放弃导入的第三方包中定义的标志

Go 如何在我的应用程序中放弃导入的第三方包中定义的标志,go,command-line,flags,Go,Command Line,Flags,考虑一下,我的应用程序使用第三方库。我希望我的应用程序只接受应用程序中定义的标志,而不接受导入包中定义的标志 package main import ( "flag" "fmt" log "github.com/golang/glog" ) var myFlag int func init() { flag.IntVar(&myFlag, "my_flag", 0, "need only my flags") confDir := "/Use

考虑一下,我的应用程序使用第三方库。我希望我的应用程序只接受应用程序中定义的标志,而不接受导入包中定义的标志

package main

import (
    "flag"
    "fmt"
    log "github.com/golang/glog"
)

var myFlag int

func init() {
    flag.IntVar(&myFlag, "my_flag", 0, "need only my flags")
    confDir := "/Users/foo/test/logs" //assume this is read from configuration file
    flag.Set("log_dir", confDir)
    flag.Parse()
}

func main() {
    flag.Parse()
    log.Errorln("flag", myFlag)
    log.V(0).Infoln("flag", myFlag)
    fmt.Println("test", myFlag)
}
在上面的代码示例中,日志包有许多标志。编译后,当我执行以下命令时,将显示所有标志,包括“my_flag”和来自日志包的标志。但是,我想用从配置文件获得的值设置代码中日志包标志的值

  -alsologtostderr
        log to standard error as well as files
  -log_backtrace_at value
        when logging hits line file:N, emit a stack trace
  -log_dir string
        If non-empty, write log files in this directory
  -logtostderr
        log to standard error instead of files
  -my_flag int
        need only my flags
  -stderrthreshold value
        logs at or above this threshold go to stderr
  -v value
        log level for V logs
  -vmodule value
        comma-separated list of pattern=N settings for file-filtered logging

如何限制我的应用程序可执行文件接受其他标志?

如果要放弃其他程序包的标志,则可以使用新的标志集,而不是默认的标志集

package main

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

var myFlag int

func main() {
    f := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
    f.IntVar(&myFlag, "my_flag", 0, "need only my flags")
    confDir := "/Users/foo/test/logs" //assume this is read from configuration file
    f.Set("log_dir", confDir)
    f.Parse(os.Args[1:])
    fmt.Println("test", myFlag)
}

如果要放弃其他包的标志,则可以使用新的标志集而不是默认的标志集

package main

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

var myFlag int

func main() {
    f := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
    f.IntVar(&myFlag, "my_flag", 0, "need only my flags")
    confDir := "/Users/foo/test/logs" //assume this is read from configuration file
    f.Set("log_dir", confDir)
    f.Parse(os.Args[1:])
    fmt.Println("test", myFlag)
}

flag
非方法的函数使用导出的包变量
CommandLine
。你可以用

flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
标志
中重置导出的包变量
命令行
。下面是一个可运行的示例:

package main

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

func main() {
    flag.Int("u", 1, "We don't want this flag")
    flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
    GoodInt := flag.Int("g", 100, "This is a flag we want!")
    flag.Parse()
    fmt.Println(*GoodInt)
}
用法示例:

$ go run program.go -h
Usage of /tmp/.../program:
  -g int
    This is a flag we want! (default 100)
exit status 2

如果您希望避免修改package变量,那么可以通过创建一个新的
标志集
来做到这一点,在我之前得到的答案演示了这一点。在这种情况下,请确保仅对新的
标记集
调用方法,并避免对
命令行
操作的
标记
函数

标记
非方法的函数使用导出的包变量
命令行
。你可以用

flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
标志
中重置导出的包变量
命令行
。下面是一个可运行的示例:

package main

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

func main() {
    flag.Int("u", 1, "We don't want this flag")
    flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
    GoodInt := flag.Int("g", 100, "This is a flag we want!")
    flag.Parse()
    fmt.Println(*GoodInt)
}
用法示例:

$ go run program.go -h
Usage of /tmp/.../program:
  -g int
    This is a flag we want! (default 100)
exit status 2

如果您希望避免修改package变量,那么可以通过创建一个新的
标志集
来做到这一点,在我之前得到的答案演示了这一点。在这种情况下,请确保只在新的
标志集
上调用方法,并避免在
命令行
上运行的
标志
函数。如果导入的包声明标志,它们将成为应用程序的一部分。使用其他软件包或对其进行修补。您不能。如果导入的包声明标志,它们将成为应用程序的一部分。使用其他包或修补程序。如果我重新分配命令行,我将无法运行任何带有“-v”、“run”等标志的测试用例“go test”。因此,我没有替换命令行变量,而是定义了自己的函数来显示标志和替换标志的详细信息。使用该函数。如果我重新分配命令行,我将无法运行任何带有任何标志(如“-v”、“-run”)的测试用例“go test”。因此,我没有替换CommandLine变量,而是定义了自己的函数来显示flags和replace flag.Usage的详细信息。