在Go中使用命令行标志

有很多使用Go处理CLI标志的方法。第一种选择是根本不使用任何库,然后检查os.Args。第二种选择是使用标准库flag包裹。第三种选择是使用许多第三方CLI库之一,例如眼镜蛇

让我们来谈谈第二种选择:使用标准库flag,因为与原始解析相比,它提供了很多好处os.Args它是内置的。

添加import "flag"到包的导入部分,就可以使用了。

接受int参数类型:

func Int(name string, value int, usage string) *int

var count = flag.Int(“count”, 5, “the count of items”) fmt.Println("count value ", *count)

第一个参数是CLI命令中使用的标志名,第二个参数是默认值,第三个参数是描述。

提供了一种替代语法flag.IntVar()

func IntVar(p *int, name string, value int, usage string)

var count int flag.IntVar(&count, “count”, 5, “the count of items”) fmt.Println("count value ", count)

在此,参数被移位,并且第一个参数是变量参考。

主要区别在于,在第一种情况下,您将获得一个指针。在第二种情况下,您可以获得价值。

flag提供许多功能来解析不同的标志类型,对于每种您要接受的类型,您都需要使用不同的标志:

func Bool(name string, value bool, usage string) *bool
func BoolVar(p *bool, name string, value bool, usage string)
func Duration(name string, value time.Duration, usage string) *time.Duration
func DurationVar(p *time.Duration, name string, value time.Duration, usage string)
func Float64(name string, value float64, usage string) *float64
func Float64Var(p *float64, name string, value float64, usage string)
func Int(name string, value int, usage string) *int
func Int64(name string, value int64, usage string) *int64
func Int64Var(p *int64, name string, value int64, usage string)
func IntVar(p *int, name string, value int, usage string)
func String(name string, value string, usage string) *string
func StringVar(p *string, name string, value string, usage string)
func Uint(name string, value uint, usage string) *uint
func Uint64(name string, value uint64, usage string) *uint64
func Uint64Var(p *uint64, name string, value uint64, usage string)
func UintVar(p *uint, name string, value uint, usage string)

为标志传递错误的类型将引发错误,暂停程序,并且所需的用法将被打印给用户。

例如,以下是解析字符串的方法:

var description = flag.String("description", "default value", "the description of the flag")

标志语法

你如何设置标志?简单:附加-flagname到CLI命令,并带有4种替代但等效的语法:

-count=x
-count x
--count=x
--count x

您可以根据需要将任意多个标志传递给命令,但这是第一次flag无法识别标志,它将停止解析其他标志。这意味着,如果您还具有非标志参数,则所有标志必须都在开头。

解析标志

定义所有标志后,您需要调用

flag.Parse()

实际解析它们。

布尔标志

布尔标志可以通过添加来设置-count,这会使布尔值标志获得true价值。设置一个false值,使用-count=false。这些值中的任何一个对于布尔标志均有效:1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False

简短的选择

在现实世界中,很多时候您会看到CLI应用程序接受带有描述性名称的标志以及带有字母缩写的同一标志。您可以通过提供2个标志处理程序来做到这一点:

var gopherType string

func init() { const ( defaultGopher = “pocket” usage = “the variety of gopher” ) flag.StringVar(&gopherType, “gopher_type”, defaultGopher, usage) flag.StringVar(&gopherType, “g”, defaultGopher, usage+" (shorthand)") }

解析非标志参数

flag程序包提供了一些方法还可以解析非标记参数。

flag.Args()

返回参数未解析为标志的字符串切片。

根据需要强制标记

flag程序包不提供针对此问题的内置解决方案。您需要自己处理这种情况:

// [...]
flag.Parse()

if *count == “” { flag.PrintDefaults() os.Exit(1) }

更高级的主题

这是一篇介绍性文章。您可以从这里进入更深入的主题,例如实现子命令和定义自己的标志类型。看https://blog.komand.com/build-a-simple-cli-tool-with-golang有关CLI的更高级用法。

参考


更多教程: